Q:为什么要用RecyclerView替代ViewPager?

A:很简单,就像从Eclipse过度到Android Studio,一去不复返(认真脸,并不是因为林檀嫌弃ViewPager)。

效果图

正文开始:

首先,林檀需要:

  1. 一个横向的RecyclerView。
  2. 一个左右滑动RecyclerView时切换TabLayout中TabItem的联动效果
  3. 一个切换TabLayout中TabItem时自动滚动RecyclerView的联动效果

大路且漫漫,咱先走几步看看:

  • 第一条需求涉及到布局属性,在Java代码中可以通过 LayoutManager设置。
...
private LinearLayoutManager mLayoutManager;
...
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
...
    mLayoutManager = new LinearLayoutManager(TimeActivity.this);//创建线性布局管理器
    mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//为线性布局管理器设置布局方向
...
}
...
  • 第二条需求即当RecyclerView被用户拖动时,更新TabLayout选中状态。因为RecyclerView没有提供类似 setupWithViewPager()这样ViewPager与TabLayout联动的方法,所以我们需要重写 RecyclerView的滑动监听事件
...
private RecyclerView mRcvTime;
private boolean mIsRcvActiveScroll;//是否为rcv激活的滚动(即用户手指滑动)
private int mRcvScrollOrientation;//滚动方向(小于0为View左滚,大于0为右滚)
private int mPosition;//记录TabLayout与RecyclerView的位置
...
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
    ...
    mRcvTime.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            switch (newState) {
                case RecyclerView.SCROLL_STATE_DRAGGING://正在被外部拖拽,一般为用户手指滑动
                    mIsRcvActiveScroll = true;
                    break;
                case RecyclerView.SCROLL_STATE_SETTLING://自动滚动开始
                    break;
                case RecyclerView.SCROLL_STATE_IDLE://停止滚动
                    break;
            }
            updateTabSelect(mRcvScrollOrientation);
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (mIsRcvActiveScroll) {
                mRcvScrollOrientation = dx;//将rcv水平滚动距离保存到成员变量中
            }
        }
    });
    ...
}

private void updateTabSelect(int dx) {
    if (mIsRcvActiveScroll) {
        if (dx > 0) {//View右滑
            mPosition = mLayoutManager.findLastVisibleItemPosition();
        }
        if (dx < 0) {//View左滑
            mPosition = mLayoutManager.findFirstVisibleItemPosition();
        }
        mTlTime.setScrollPosition(mPosition, 0F, true);
    }
}//更新TabLayout的选中的TabItem
...
  • 第三条需求即当TabLayout中的TabItem被用户点击时,触发RecyclerView的滚动事件。同样,我们需要重写TabLayout的选择监听事件。
...
private TabLayout mTlTime;
...
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
    ...
    mTlTime.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            mIsRcvActiveScroll = false;
            int tabPosition = tab.getPosition();
            mRcvTime.smoothScrollToPosition(tabPosition);
        }//首次选择的逻辑处理

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
        }//取消选择(即选择其他TabItem时)的逻辑处理

        @Override
        public void onTabReselected(TabLayout.Tab tab) {
            onTabSelected(tab);
        }//再次选择时的逻辑处理
    });
    ...
}
分类: PL_Android

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。