欢迎访问宙启技术站
智能推送

recycleview实现拼多多首页水平滑动效果

发布时间:2023-05-14 02:30:27

RecycleView是Android的一个高级显示列表的View,它提供了一种比ListView更加灵活的方式来展示大型的数据集。RecycleView需要一个LayoutManager来决定它所代表的列表应该如何布局。RecyclerView是用起来非常灵活的控件,特别是ItemAnimator的实现可以很容易的实现水平滑动的效果,接下来我们来通过实现拼多多首页水平滑动效果来介绍如何使用RecycleView来实现。

1.使用RecycleView实现水平滑动的效果必须先要重写LayoutManager的两个方法:

public class HorizontalLayoutManager extends LinearLayoutManager {

    public HorizontalLayoutManager(Context context) {
        super(context);
        setOrientation(HORIZONTAL);
    }

    public HorizontalLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    @Override
    public boolean canScrollHorizontally() {
        return true;
    }

    @Override
    public boolean canScrollVertically() {
        return false;
    }
}

其中,canScrollHorizontally()方法返回true表示支持水平滑动,canScrollVertically()方法返回false表示不支持垂直滑动。以上是支持单行水平滑动的重写方法,只需改变水平和垂直的位置,就能支持单列的垂直滑动。如果需要支持多行或多列的滑动,需要对上述方法进行修改。

2.实现ViewPager效果的滑动,需要使用RecyclerView的ItemAnimator来实现。我们通过继承DefaultItemAnimator来实现:

public class HorizontalItemAnimator extends DefaultItemAnimator {

    @Override
    public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
        // 改变时需要执行的过渡动画
        return super.animateChange(oldHolder, newHolder, fromX, fromY, toX, toY);
    }

    @Override
    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) {
        // 是否允许更新ViewHolder
        return true;
    }

    @Override    
    public boolean canAnimateAppearance(@NonNull RecyclerView.ViewHolder viewHolder, @Nullable ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
        // 是否允许动画出现
        return true;
    }

    @Override    
    public boolean canAnimateDisappearance(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull ItemHolderInfo preLayoutInfo, @Nullable ItemHolderInfo postLayoutInfo) {
        // 是否允许动画消失
        return true;
    }

    @Override    
    public boolean canAnimatePersistence(@NonNull RecyclerView.ViewHolder viewHolder, @NonNull List<Object> payloads) {
        // 是否允许动画持久化
        return true;
    }

    @Override    
    public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
        // 是否可重用Updated ViewHolder
        return true;
    }

    @Override    
    public void runPendingAnimations() {
        // 开始动画
        super.runPendingAnimations();
    }

    @Override    
    public void endAnimation(@NonNull RecyclerView.ViewHolder item) {
        // 结束动画
        super.endAnimation(item);
    }

    @Override    
    public void endAnimations() {
        // 结束全部动画
        super.endAnimations();
    }

    @Override    
    public void onAnimationStarted(@NonNull RecyclerView.ViewHolder item) {
        // 动画开始
        super.onAnimationStarted(item);
    }

    @Override    
    public void onAnimationFinished(@NonNull RecyclerView.ViewHolder item) {
        // 动画结束
        super.onAnimationFinished(item);
    }

    @Override    
    public void onRemoveStarting(RecyclerView.ViewHolder item) {
        // 移除开始
        super.onRemoveStarting(item);
    }

    @Override    
    public void onRemoveFinished(RecyclerView.ViewHolder item) {
        // 移除结束
        super.onRemoveFinished(item);
    }

    @Override    
    public void onAddStarting(RecyclerView.ViewHolder item) {
        // 添加开始
        super.onAddStarting(item);
    }

    @Override    
    public void onAddFinished(RecyclerView.ViewHolder item) {
        // 添加结束
        super.onAddFinished(item);
    }

    @Override    
    public void onChangeStarting(RecyclerView.ViewHolder item, boolean oldItem) {
        // 改变开始
        super.onChangeStarting(item, oldItem);
    }

    @Override    
    public void onChangeFinished(RecyclerView.ViewHolder item, boolean oldItem) {
        // 改变结束
        super.onChangeFinished(item, oldItem);
    }
}

在实现的过程中, 个方法animateChange()是必须要重写的,其他的方法只需要根据需要来选择重写即可。

3.实现RecycleView的滑动效果需要在xml文件中设置相关属性:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:overScrollMode="never"
    android:scrollbars="none"
    app:layoutManager="com.example.recyclerviewdemo.HorizontalLayoutManager" />

overScrollMode属性设置为never表示滑动结束时不会出现滑动到边界时的阴影效果,scrollbars属性设置为none表示不需要显示滑动条。

4.在代码中设置RecyclerView的属性,以便实现水平滑动效果:

RecyclerView recyclerView = findViewById(R.id.rv_horizontal);
HorizontalLayoutManager layoutManager = new HorizontalLayoutManager(this); // 设置布局管理器
layoutManager.setInitialPrefetchItemCount(10);
recyclerView.setLayoutManager(layoutManager); // 设置RecyclerView的布局管理器
recyclerView.setItemAnimator(new HorizontalItemAnimator()); // 设置RecyclerView的动画
recyclerView.setHasFixedSize(true);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setAdapter(new MyAdapter());

5.相关自定义方法的实现:

// 设置条目点击事件
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        Toast.makeText(MainActivity.this, "点击了:" + mAdapter.datas.get(position), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onItemLongClick(View view, int position) {
        Toast.makeText(MainActivity.this, "长按了:" + mAdapter.datas.get(position), Toast.LENGTH_SHORT).show();
    }
}));

// 设置RecyclerView的滑动效果
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);

以上代码实现了RecycleView实现拼多多首页水平滑动效果,通过本文的介绍,相信大家已经了解了RecycleView的用法,以及滑动条和ItemAnimator的实现方式。