欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

NestedScrollView嵌套viewpager不显示内容解决方案

程序员文章站 2022-05-04 19:18:13
NestedScrollView嵌套viewpager不显示内容总得来说为什么出现这种情况,NestedScrollView里面只能有一个ViewGroup,一般是LinearLayout,而为什么显示不出来,就是 NestedScrollView 计算高度在viewpager 渲染呈现前面执行了,所以viewpager高度一直为0,多么悲伤。先前在低于Android 9 以下版本开发的时候 在NestedScrollView 控件属性中加入android:fillViewport=“true” 充满布...

NestedScrollView嵌套viewpager不显示内容

总得来说为什么出现这种情况,NestedScrollView里面只能有一个ViewGroup,一般是LinearLayout,而为什么显示不出来,就是 NestedScrollView 计算高度在viewpager 渲染呈现前面执行了,所以viewpager高度一直为0,多么悲伤。

先前在低于Android 9 以下版本开发的时候 在NestedScrollView 控件属性中加入android:fillViewport=“true” 充满布局属性还起作用,之后就无效了。

下面根据网上的各种方案,总结优化修改,给viewpager 重写一遍测量,重新给测量高度;在每次测完后将测量得到的高度保存下来,下次viewpager 再切换回来就可以直接设置高度了,就没有必要每次都重新计算一遍高度。

注:设置了viewpager.setPageMargin(30); 属性,本代码保存的高度可能会有偏差,内容少的页会受内容多的页面影响,底部会出现空白。

被坑了很久,很悲伤,代码从开源来,就回归开源。

好了下面直接上代码:

public class AutoHeightViewPager extends ViewPager {

    private int mHeight = 0;
    private int mCurPosition = 0;//已经获取到的高度下标
    private int mPosition = 0;//当前显示下标

    private HashMap<Integer, Integer> mChildrenViews = new LinkedHashMap<Integer, Integer>();//按下标存储View历史高度
    private HashMap<Integer, Boolean> indexList = new LinkedHashMap<Integer, Boolean>();//记录页面是否存储了高度


    /**
     * 做自适应高度,必须先进行初始化标记
     */
    public void initIndexList(int size) {
        mHeight = 0;
        mCurPosition = 0;
        mPosition = 0;
        for (int i = 0; i < size; i++) {//初始化高度存储状态
            indexList.put(i, false);
        }
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = 0;
        if (indexList.size() > 0) {
            if (indexList.get(mPosition)) {
                height = mChildrenViews.get(mPosition);
            } else {
                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) {
                        height = h;
                    }
                }
                mHeight = height;
            }
        }

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

        LogUtils.d("AutoHeightViewPager", "height=" + height + "  pos=" + mCurPosition);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 在viewpager 切换的时候进行更新高度
     */
    public void updateHeight(int current) {
        this.mPosition = current;
        if (indexList.size() > 0) {
            LogUtils.d("AutoHeightViewPager", "updateHeight 1 current=" + current + "   mCurPosition=" + mCurPosition);
            saveIndexData();
            if (indexList.get(current)) {
                int height = 0;
                if (mChildrenViews.get(current) != null) {
                    height = mChildrenViews.get(current);
                }
//                LogUtils.d("AutoHeightViewPager", "updateHeight 2=" + height + "   pos=" + current);
                LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) getLayoutParams();
                if (layoutParams == null) {
                    layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, height);
                } else {
                    layoutParams.height = height;
                }
                setLayoutParams(layoutParams);
            }
            this.mCurPosition = current;
        }
    }

    /**
     * 保存已经测绘好的高度
     */
    private void saveIndexData() {
        if (!indexList.get(mCurPosition)) {//没保存高度时,保存
            indexList.put(mCurPosition, true);
            mChildrenViews.put(mCurPosition, mHeight);
            LogUtils.d("AutoHeightViewPager", "saveIndexData 1=" + mHeight + "   mCurPosition=" + mCurPosition);
        }
    }

}

使用方法

		//初始化记录是否保存高度的下标
		//注:在重新刷新加载页面的时候,需要对下标进行重新初始化
		viewpager.initIndexList(fragments.size());
		//添加viewpager 切换监听
		viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int i, float v, int i1) {

            }

            @Override
            public void onPageSelected(int i) {
            	//在每次切换的时候更新高度
                viewpager.updateHeight(i);
            }

            @Override
            public void onPageScrollStateChanged(int i) {

            }
        });
		

本文地址:https://blog.csdn.net/sinat_28864443/article/details/107504230