ViewPager高度自适应

ViewPager用的很多,比如广告条等等,可是高度却不能自适应内容,总是会占满全屏,即使设置android:height=”wrap_content”也是没有用的。后来通过网上搜索,发现了几个思路:

一、使用LinearLayout布局,利用其使用weight来自动调整ViewPager的高度;
二、使用高度固定写死的方法来解决;
三、通过自定义ViewPager,重写其onMeasure方法;
四、最后是通过代码来动态的获取ViewPager的子View高度,然后将这个高度赋值给ViewPager。

我们现在就来说说每个方法的使用:
首先第一个,适用于父布局占据整个屏幕的时候,如图:


使用方法(代码和效果图片不一样,只是这里举例说明使用方法):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical" >

    <android.support.v4.view.ViewPager
 android:id="@+id/pager"
 android:layout_width="fill_parent"
 android:layout_height="0dp"
 android:layout_weight="1.0" />

    <ImageView
 android:id="@+id/ivCursor"
 android:layout_width="60dp"
 android:layout_height="5dp"
 android:scaleType="fitCenter"
 android:src="@drawable/cursor" />

    <LinearLayout
 android:id="@+id/tabs"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content" />

</LinearLayout>
  • 1

第二种、使用高度固定写死的方法来解决。这种情况需要使用的ViewPager里面的内容全部固定尺寸,不需要随着设备屏幕的变变化而变化,所以屏幕适配就不达标。具体使用情况可以考虑定制设备的项目,比如银行的交互式平板,设备提供商软件部分就可以这么干,因为只有这一种设备来使用程序。

第三种情况就是通过自定义ViewPager,重写其onMeasure方法。适用于ViewPager的子View高度一定,比如最大化或者固定尺寸,使用后效果如上面地图效果。但是这种方法也有局限性,不良效果如图片:

这里ViewPager里面包裹的Fragment使用了Gridview且Gridview高度自适应,在onMeasure中返回childView的高度就只有Gridview默认的一排内容高度。

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;

public class WrapContentHeightViewPager extends ViewPager {

    public WrapContentHeightViewPager(Context context) {
        super(context);
    }

    public WrapContentHeightViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int height = 0;
        //下面遍历所有child的高度
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.measure(widthMeasureSpec,
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            int h = child.getMeasuredHeight();
            if (h > height) //采用最大的view的高度。
                height = h;
        }

        heightMeasureSpec = MeasureSpec.makeMeasureSpec(height,
                MeasureSpec.EXACTLY);

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
  • 1

最后一种方法,使用代码动态的获取Fragment高度,然后将高度赋值给ViewPager。先上代码然后讲解:

/**
 * 设置ViewPager的自适应
 * @param childViewHeight
 */
    private void setViewPagerWrapContentHeight(int childViewHeight)
    {

        int viewPagerIndex = main.indexOfChild(viewPager);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, childViewHeight );//这里设置params的高度。
          main.removeView(viewPager);
         main.addView(viewPager, viewPagerIndex , params);//使用这个params
    }
  • 1

mian代表父布局,这里要注意,如果父布局是LinearLayout或者其它布局,那么main声明的时候就是这个布局,不能声明为View或者其它布局,否则这里容易造成类型转换异常。这一句代码也很简单,就是获取ViewPager在父布局的子View中排行老几?
LinearLayout.LayoutParams这个参数根据父布局来定,切忌不要用了父布局的子类或者与父布局无关的类(即只能用父布局本身或者其父类),否则这里设置高度的时候会造成类型转换异常。这一句代码就是设置一个属性宽度最大、高度为给定的childViewHeight的一个属性params。
如果上面两句代码代码照做了,后面就没有问题了,代码执行逻辑是删除ViewPager,然后马上在之前ViewPager的位置加上ViewPager,且对其属性修改为我们刚刚设置的属性。

Tip:这里我也不明白为什么ViewPager的属性是LinearLayout.LayoutParams,因为viewgroup的属性没有带参数的方法,或许LinearLayout是ViewPager的父类或者是祖宗类,这里求知道因由的大神在评论处解释一下,谢谢!

setViewPagerWrapContentHeight这个方法在什么地方调用我就不说了,最后唠叨一点,子View高度怎么取?我是在ViewPager包裹的Fragment的OnCreateView方法里面使用handler传回来的。这里要注意,直接在OnCreateView方法方法里面取view.getHeight()只能得到0,这里正确打开姿势是这样的:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) 
    {
        View layout = inflater.inflate(R.layout.emoji_icon_fragment, container, false);
        mGridView = (GridView) layout.findViewById(R.id.gview);
        EmojiFragmentAdapter adapter = new EmojiFragmentAdapter(getActivity(), bitmapData);
        mGridView.setAdapter(adapter);
        mGridView.setOnItemClickListener(this);
        mGridView.post(new Runnable() {

            @Override
            public void run() {
                handler.sendEmptyMessage(mGridView.getHeight());

            }
        });
        return layout;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春哥111

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值