切换ViewPager中的内容时,由于各fragment中的数据长度不一致,数据长度短的页面会出现空白

布局层级为NestedScrollView-ViewPager-Fragment-RecyclerView的布局,切换ViewPager中的内容时,部分页面底部出现空白

我们的app首页中有一个模块的布局层级为NestedScrollView-ViewPager-Fragment-RecyclerView,每一页以列表的形式显示数据。由于有的页面列表数据多,有的页面数据少,每个页面的数据长度不一致,数据少的页面会出现空白页面。这是不同的RecyclerView的外层是同一个ViewPager,数据长的页面将ViewPager撑长了导致的。

对于这个问题的解题思路主要分两步。
一、自定义ViewPager,内部会有一个列表HashMap<Integer, View> mChildrenViews,用于缓存加入的View,在构建相应的fragment的时候,将 viewPager对象和当前fragment的位置mPosition传入fragment中;然后在fragment的onCreateView中调用mViewPager.setObjectForPosition(rootView, mPosition)缓存view;
二、每次切换的时候,通过ViewTreeObserver.OnGlobalLayoutListener获取到当前RecyclerView的高度,然后动态的修改ViewPager的高度,在setUserVisibleHint方法中添加OnGlobalLayoutListener监听

下面是主要代码

public class AutofitHeightViewPager extends ViewPager {
private int current;
private int height = 0;
/**
* 保存position与对于的View
*/
private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();

private boolean scrollble = true;

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

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


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (mChildrenViews.size()!=0&&mChildrenViews.containsKey(current)) {
        View child = mChildrenViews.get(current);
        child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        height = child.getMeasuredHeight();
    }

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

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public void resetHeight(int current,int height) {
    this.current = current;
    if (mChildrenViews.size()>=current) {
        ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) getLayoutParams();
        if (layoutParams == null) {
            layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height);
        } else {
            layoutParams.height = height;
        }
        setLayoutParams(layoutParams);
    }
}

/**
 * 保存position与对于的View
 */
public void setObjectForPosition(View view, int position)
{
    mChildrenViews.put(position, view);
}


@Override
public boolean onTouchEvent(MotionEvent ev) {
    if (!scrollble) {
        return true;
    }
    return super.onTouchEvent(ev);
}

}

private ViewTreeObserver.OnGlobalLayoutListener mOnGlobalLayoutListener= new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //传入 RecyclerView 高度,并做一些 Adapter 的初始化工作
        if (rcList != null){
            int height = rcList.getHeight();

            if (height != 0 && lastHeight != height){
                lastHeight =height;
                Logger.d("height:"+height);
                rcList.getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
                mViewPager.resetHeight(mPosition, height);
            }

        }

    }
};

public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser){
        if (lastHeight != 0){
            mViewPager.resetHeight(mPosition,lastHeight);
        }else {
            if (rcList != null){
                rcList.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
            }
        }
    }else {
        if (rcList != null){
            rcList.getViewTreeObserver().removeOnGlobalLayoutListener(mOnGlobalLayoutListener);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值