Skip to content
jrfeng edited this page Jan 24, 2022 · 9 revisions

rv-helper 提供了以下几个 RecyclerView 帮助类:

  • ItemClickHelper:用于帮助处理 RecyclerView 中列表项的 “点击/长按点击” 事件。
  • SelectableHelper:用于帮助实现 RecyclerView 中列表项的 单选与多选 功能。
  • ScrollToPositionHelper:滚动到 RecyclerView 的某一 Item 位置时对该 Item背景闪动动画
  • PositionHelper:用于帮助维护 RecyclerView 中列表项的序号。

ItemClickHelper

功能:用于帮助处理 RecyclerView 中列表项的 “点击/长按点击” 事件。

可用于处理列表项视图中任意一个或多个 View 的 “点击/长按点击” 事件。

使用步骤:

  1. 创建一个 ItemClickHelper 对象;
  2. 调用 attachToRecyclerView(RecyclerView) 方法将 ItemClickHelper 对象附件到一个 RecyclerView 对象上;
  3. (可选)调用 setOnItemClickListener(OnItemClickListener) 设置 “点击” 事件 监听器;
  4. (可选)调用 setOnItemLongClickListener(OnItemLongClickListener) 设置 “长按点击” 事件监听器;
  5. RecyclerView.AdapteronBindViewHolder 方法中调用 bindClickListener(View...) 方法绑定某个或多个 View 的 “点击” 事件监听器;
  6. 调用 bindLongClickListener(View...) 方法绑定某个或多个 View 的 “长按点击” 事件监听器。

当不再需要 ItemClickHelper 对象时,应该调用 detach() 方法进行分离。建议在 RecyclerView.AdapteronDetachedFromRecyclerView 方法中调用该方法。

例:

public abstract class ItemClickableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
     private ItemClickHelper mItemClickHelper = new ItemClickHelper();

     @Override
     public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
         super.onAttachedToRecyclerView(recyclerView);

         // 附加到 RecyclerView 对象上
         mItemClickHelper.attachToRecyclerView(recyclerView);
     }

     @Override
     public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
         super.onDetachedFromRecyclerView(recyclerView);

         // 分离 mItemClickHelper
         mItemClickHelper.detach();
     }

     @Override
     public void onBindViewHolder(@NonNull VH holder, int position) {

         // 绑定列表项的 “点击” 事件
         mItemClickHelper.bindClickListener(holder.itemView);

         // 绑定列表项的 “长按点击” 事件
         mItemClickHelper.bindLongClickListener(holder.itemView);
     }

     public void setOnItemClickListener(ItemClickHelper.OnItemClickListener listener) {
         mItemClickHelper.setOnItemClickListener(listener);
     }

     public void setOnItemLongClickListener(ItemClickHelper.OnItemLongClickListener listener) {
         mItemClickHelper.setOnItemLongClickListener(listener);
     }
 }

如果你仅关心列表项的点击事件,那么继承 ItemClickableAdapter 类可能是更好的选择。

SelectableHelper

功能:用于帮助实现 RecyclerView 中列表项的单选与多选功能。

使用步骤:

  1. 创建一个 SelectableHelper 对象;
  2. ViewHolder 需要实现 SelectableHelper.Selectable 接口,以便根据选中状态更新 UI。
  3. 调用 attachToRecyclerView(RecyclerView) 方法将当前 SelectableHelper 对象 附加到一个 RecyclerView 对象上;
  4. RecyclerView.AdapteronBindViewHolder 方法中调用当前 SelectableHelper 对象的 updateSelectState(RecyclerView.ViewHolder, int) 方法。

当不再需要一个 SelectableHelper 对象时,应该调用它的 detach() 方法分离它。建议在 RecyclerView.AdapteronDetachedFromRecyclerView 方法中调用该方法。

例:

public abstract class SelectableAdapter<Holder extends RecyclerView.ViewHolder & SelectableHelper.Selectable>
        extends RecyclerView.Adapter<Holder> {
    private SelectableHelper mSelectableHelper;
    ...

    public SelectableAdapter() {
        mSelectableHelper = new SelectableHelper(this);
        ...
    }

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        mSelectableHelper.attachToRecyclerView(recyclerView);
        ...
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);

        mSelectableHelper.detach();
        ...
    }

    @Override
    public void onBindViewHolder(@NonNull Holder holder, int position) {
        mSelectableHelper.updateSelectState(holder, position);
        ...
    }

    ...
}

为了避免多余的模板代码,你可以继承 SelectableAdapter 类。

ScrollToPositionHelper

功能:滚动到 RecyclerView 的某一 Item 位置时对该 Item 做背景闪动动画。

注意!该帮助类最低支持版本为 API Level 16

默认情况下,背景闪动动画的颜色为黄色(Color.YELLOW);持续时为 300ms;插值器为 LinearInterpolator

可以调用 setAnimDuration(int) 方法和 setAnimInterpolator(TimeInterpolator) 方 法设置动画的持续时间与插值器。

使用步骤:

  1. 创建一个 ScrollToPositionHelper 对象;
  2. 当要滚动到 RecyclerView 的某个位置时, 调用该对象的 scrollToPosition(int) 或者 smoothScrollToPosition(int) 方法即可。

例:

ScrollToPositionHelper helper = new ScrollToPositionHelper(recyclerView);
helper.scrollToPosition(40);

PositionHelper

功能:用于帮助维护 RecyclerView 中列表项的序号。

RecyclerView 中的列表项发生增加、删除、移动时,ViewHolder 无法感知到其顺序发生了改变。如果开发者仅在 onBindViewHolder 时使用 adapter position 来设置列表项的序号,由于列表项的数据并没有发生改变,因此不会重新绑定 ViewHolder,这就会导致列表项显示一个错误的序号。PositionHelper 可以帮助开发者处理这个问题,它能感知到列表项的增加、删除、移动事件,并且可以在 ViewHolderadapter position 发生改变时向其发出通知。

使用步骤:

  1. 创建一个 PositionHelper 对象;
  2. 调用 attachToRecyclerView(RecyclerView) 方法将当前 PositionHelper 对象 附加到一个 RecyclerView 对象上;
  3. ViewHolder 需要实现 PositionHelper.OnPositionChangeListener 接口。

例:

public class PositionAdapter extends RecyclerView.Adapter<PositionAdapter.ViewHolder> {
    ...
    private PositionHelper<ViewHolder> mPositionHelper;

    PositionAdapter(@NonNull List<String> items) {
        ...
        mPositionHelper = new PositionHelper<>(this);
    }

    ...

    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        // 附加到 RecyclerView
        mPositionHelper.attachToRecyclerView(recyclerView);
    }

    @Override
    public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);

        // 分离 PositionHelper
        mPositionHelper.detach();
    }

    // ViewHolder 需要实现监听器接口
    public static class ViewHolder extends RecyclerView.ViewHolder implements PositionHelper.OnPositionChangeListener {
        public TextView tvPosition;
        ...

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            tvPosition = itemView.findViewById(R.id.tvPosition);
            ...
        }

        @Override
        public void onPositionChanged(int oldPosition, int newPosition) {
            // 更新 ViewHolder 的序号
            tvPosition.setText(String.valueOf(newPosition));
        }
    }
}

End

Clone this wiki locally