动态设置View的宽高、宽高比例(设置ViewPager的高度,宽高比例为2:1)

利用ViewPager显示banner的时候,一些人会直接写死ViewPager高度,比如在xml布局里面直接写成180dp。

这样的话,每个手机的宽度不同,viewpager里面内容的长宽比就不同,如果显示图片的话,里面的内容就很可能会变形。


本例在代码中动态设置ViewPager的高度,让他的高度始终和宽度呈固定比例。比如宽高比例是2:1,只要让后台配置的图片都是按2:1的话,图片显示就不会变形,体验明显提高一个档次。


本例将使用上一篇博客的代码,增加一些内容就行。上篇博客:Android ViewPager实现无限循环(2.加入小圆点,优化自动和手动滑动冲突)


布局基本没什么改变

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/rl_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v4.view.ViewPager
            android:id="@+id/vp_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:id="@+id/ll_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="10dp"
            android:gravity="center"
            android:orientation="horizontal" />
    </RelativeLayout>
</RelativeLayout>


再看看代码

private RelativeLayout mRelativeLayout;

mRelativeLayout = (RelativeLayout) findViewById(R.id.rl_main);

/**
         * 动态设置代码高度
         * addOnPreDrawListener,顾名思义,在view要显示之前将会回调
         */
        mRelativeLayout.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                mRelativeLayout.getViewTreeObserver().removeOnPreDrawListener(this);
                ViewGroup.LayoutParams layoutParams = mRelativeLayout.getLayoutParams();
                layoutParams.height = (int) (mRelativeLayout.getWidth() / 2);
                mRelativeLayout.setLayoutParams(layoutParams);
                return true;
            }
        });

增加的内容也非常的少

注册一个监听器,在view要显示之前会回调他。在回调的时候,把view的宽度取出来,如果你的需求是高度为宽度的一半,就除了2。

注意:removeOnPreDrawListener一定要记得调用,不然会无限次的触发onPreDraw方法。


当然了,也有其它的方法,比如你直接获取手机屏幕的宽度,再除以2也行。

但是ViewPager不一定是横向铺满全屏,可能设置有margin个5dp之类的,你就要在代码中将dp转成px,再用屏幕宽度减去它。

或者一些时候view的宽高因为其它的一些原因而要在运行时才能确定的,但又要求要固定比例的时候,用这个方法就好解决了。


以下三张截图演示ViewPager不同margin情况时候的显示


当没有margin时



当左右margin都为30dp时



当左右margin为80dp时


可以看到ViewPager的宽度比高度都是2:1


最后再给个提示,onPreDraw方法里面不只是能够把自己的LayoutParams取出来,在保证其它view已经被系统设置好宽高的时候,也可以拿其它的view的LayoutParams来操作,比如可以拿他的父view,因为在子要显示之前,父view的宽高已经确定了(至少我目前用过的都是正确的)。


比如有一个需求,横着放三个按钮(或图片),三个按钮都是正方的,就像微信朋友圈、qq空间发9张图片的时候,一行是3张正方形且铺满屏幕的图片,就可以用这样的代码来做:

mChildView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                mChildView.getViewTreeObserver().removeOnPreDrawListener(this);
                ViewGroup.LayoutParams layoutParams = mChildView.getLayoutParams();

                // 让子view的宽度为父view的3分之1
                layoutParams.height = mParentView.getWidth() / 3;

                // 如果你的每两个相邻view的间隔是x大小的话,还要减去这个值
//                layoutParams.height = mParentView.getWidth() / 3 - 2 * x;

                mChildView.setLayoutParams(layoutParams);
                return true;
            }
        });


源码下载  点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值