优秀案例

RecyclerView实现类似ViewPager左右滑动效果

2017-04-12  本文已影响318人  sugarhans

从 API 16 开始,控件Gallery已被废弃,此时我们可以用RecyclerView实现类似于ViewPager的横向移动。

效果图.png

布局文件很简单就一个RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.hans.hansrecyclergallery.MainActivity"
    >

    <android.support.v7.widget.RecyclerView
      android:id="@+id/rv"
      android:layout_marginTop="200dp"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      ></android.support.v7.widget.RecyclerView>


</android.support.design.widget.CoordinatorLayout>

实现方案:

1.继承RecyclerView.Adapter<ViewHolder>实现onCreateViewHolder方法,初始化itemView的大小和透明度:

  @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    ViewHolder holder = super.onCreateViewHolder(parent, viewType);
    // 设置Item的宽度
    holder.getConvertView().setScaleX(mScale);
    holder.getConvertView().setScaleY(mScale);
    holder.getConvertView().setAlpha(mAlpha);
    ViewGroup.LayoutParams lp = holder.getConvertView().getLayoutParams();
    lp.width = getItemStdWidth();//每个item所占屏幕的宽度
    return holder;
  }

2.实现onAttachedToRecyclerView(RecyclerView mRecyclerView)方法,给RecyclerView添加setOnScrollListener监听器,根据RecyclerView滑动的距离实现动画效果:

@Override public void onScrolled(RecyclerView mRecyclerView, int dx, int dy) {
        //mCurrentItemOffset += dx;
        mCurrentItemOffset = mRecyclerView.computeHorizontalScrollOffset();
        mCurrentItemPos = (int) ((mCurrentItemOffset * 1.0 / getItemStdWidth())+0.1f);
        mMiddleItemPos = getMiddlePosition();
        int offset = (mCurrentItemPos+1)*getItemStdWidth() - mCurrentItemOffset ;
        float percent = (float) Math.max(Math.abs(offset)*1.0 / getItemStdWidth(), 0.0001);

        if (mMiddleItemPos > 0) {
          leftView = mRecyclerView.getLayoutManager().findViewByPosition(mMiddleItemPos - 1);
        }
        currentView = mRecyclerView.getLayoutManager().findViewByPosition(mMiddleItemPos);
        if (mMiddleItemPos < mRecyclerView.getAdapter().getItemCount() - 1) {
          rightView = mRecyclerView.getLayoutManager().findViewByPosition(mMiddleItemPos + 1);
        }

        if (leftView != null) {
          // y = (1 - mScale)x + mScale
          leftView.setScaleY(mScale);
          leftView.setScaleX(mScale);
        }


        if (currentView != null) {
          // y = (mScale - 1)x + 1
          currentView.setScaleY((1 - mScale) * percent + mScale);
          currentView.setScaleX((1 - mScale) * percent + mScale);
          currentView.setAlpha((1 - mAlpha) * percent + mAlpha);
        }
        if (rightView != null) {
          // y = (1 - mScale)x + mScale
          rightView.setScaleY((mScale - 1) * percent + 1);
          rightView.setScaleX((mScale - 1) * percent + 1);
          rightView.setAlpha((mAlpha - 1) * percent + 1);
        }
        super.onScrolled(mRecyclerView, dx, dy);
      }
    });
    super.onAttachedToRecyclerView(mRecyclerView);
  }

3.使用LinearSnapHelper,有点类似 ViewPagerLinearSnapHelper 保证了每次滚动完自动滑动到中心的 Item

new LinearSnapHelper().attachToRecyclerView(recyclerView)

注:LinearSnapHelper支持库,需要把Support RecyclerView包更新到24.2.0以上

我们来看看效果吧:

附:源代码

上一篇下一篇

猜你喜欢

热点阅读