1. 程式人生 > >Android XRecyclerView最簡單的item點選事件處理

Android XRecyclerView最簡單的item點選事件處理

以前一直都是用PullToRefresh,後來覺得還是太out了。現在很多人都是用RecyclerView,很簡單的用法,佈局多樣化,主要是有瀑布流。這才知道RecyclerView.LayoutManager真正的強大。

但是說要addHeaderView這個的話,RecyclerView沒有實現,所以我用了XRecyclerView,其實它也是在RecyclerView的基礎上再次封裝的,用起來還是蠻好的。一個字爽。。。

這裡說一下,正確的使用XRecyclerView點選item做事件處理的問題。其實就是在RecyclerView.ViewHolder裡面的item做點選,那麼設計到一個問題就是如何簡單使用了。

一般我們會直接在item佈局中的最外層設定一個id=”@+id/…”,然後在onBindViewHolder中用holder.**.setOnClickListener()進行事件處理,你看看你是不是這樣做的,如果這樣做的話,那就繼續往下看,教你簡單的。

簡單使用item的點選事件

1、先看下RecyclerView.ViewHolder原始碼是怎麼寫的

/**
 * A ViewHolder describes an item view and metadata about its place within the RecyclerView.
 *
 * <p>{@link Adapter} implementations should subclass ViewHolder and add fields for caching
 * potentially expensive {@link View#findViewById(int)} results.</p>
 *
 * <p>While {@link LayoutParams} belong to the {@link LayoutManager},
 * {@link ViewHolder ViewHolders} belong to the adapter. Adapters should feel free to use
 * their own custom ViewHolder implementations to store data that makes binding view contents
 * easier. Implementations should assume that individual item views will hold strong references
 * to <code>ViewHolder</code> objects and that <code>RecyclerView</code> instances may hold
 * strong references to extra off-screen item views for caching purposes</p>
 */
public static abstract class ViewHolder { public final View itemView; ....... public ViewHolder(View itemView) { if (itemView == null) { throw new IllegalArgumentException("itemView may not be null"); } this.itemView = itemView; } ....... }

2、再來看看我們繼承它做了什麼事情

public class XRViewHolder extends RecyclerView.ViewHolder {
    public XRViewHolder(View view) {
        super(view);
        ButterKnife.bind(this, view);
    }
    .......
    public void onBindViewHolder(VH holder, final int position) {
        if (position >= 0) {
            holder.itemView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    itemClick(getItem(position), position);
                }
            });
        }
    }
}

看到我們自定義的XRViewHolder的構造方法中也用到了super(view)。

其實這裡的view就是item的佈局,這樣的話,我們要實現點選事件就很容易了,可以直接在用holder.itemView.setOnClickListener

item的點選錯位問題

用XRecyclerView.getChildAt(position).setOnClickListener()出現錯位問題,如果你在addHeaderView就會出現這種錯位的問題會更加明顯,可以先來看看XRecyclerView裡面的部分原始碼。

public class XRecyclerView extends RecyclerView {

  private WrapAdapter mWrapAdapter;
  ......

  public void addHeaderView(View view) {
    sHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size());
    mHeaderViews.add(view);
    if (mWrapAdapter != null) {
        mWrapAdapter.notifyDataSetChanged();
    }
  }

  ......
  private class WrapAdapter extends RecyclerView.Adapter<ViewHolder> {

  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      if (viewType == TYPE_REFRESH_HEADER) {
          return new SimpleViewHolder(mRefreshHeader);
      } else if (isHeaderType(viewType)) {
          return new SimpleViewHolder(getHeaderViewByType(viewType));
      } else if (viewType == TYPE_FOOTER) {
          return new SimpleViewHolder(mFootView);
      }
      return adapter.onCreateViewHolder(parent, viewType);
  }
}

當我們每次addHeaderView時他都會進行notifyDataSetChanged,而且在onCreateViewHolder也有了對應的isHeaderType判斷,所以當你想選擇第一個item做事件處理時可能就pos=0是屬於headerview。

總結

item點選事件簡單方便快捷的方式:holder.itemView.setOnClickListener()