我正在探索RecyclerView,我很惊讶地看到,RecyclerView没有onItemClickListener()。

我有两个问题。

主要问题

我想知道为什么谷歌删除onItemClickListener()?

是否存在性能问题或其他问题?

次要的问题

我解决了我的问题写onClick在我的RecyclerView。适配器:

public static class ViewHolder extends RecyclerView.ViewHolder implements OnClickListener {

    public TextView txtViewTitle;
    public ImageView imgViewIcon;

    public ViewHolder(View itemLayoutView) {
        super(itemLayoutView);
        txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.item_title);
        imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.item_icon);
    }

    @Override
    public void onClick(View v) {

    }
}

这样可以吗/有更好的办法吗?


当前回答

看看我的方法:

首先像这样声明一个接口:

/**
 * Interface used for delegating item click events in a {@link android.support.v7.widget.RecyclerView}
 * Created by Alex on 11/28/2015.
 */
  public interface OnRecyclerItemClickListener<T> {

     /**
      * Called when a click occurred inside a recyclerView item view
      * @param view that was clicked
      * @param position of the clicked view
      * @param item the concrete data that is displayed through the clicked view
      */
      void onItemClick(View view, int position, T item);
   }

然后创建适配器:

public class CustomRecyclerAdapter extends RecyclerView.Adapter {      

    private class InternalClickListener implements View.OnClickListener{

      @Override
      public void onClick(View v) {
        if(mRecyclerView != null && mItemClickListener != null){
            // find the position of the item that was clicked
            int position = mRecyclerView.getChildAdapterPosition(v);
            Data data = getItem(position);
            // notify the main listener
            mItemClickListener.onItemClick(v, position, data);
        }
    }
}

private final OnRecyclerItemClickListener mItemClickListener;
private RecyclerView mRecyclerView;    
private InternalClickListener mInternalClickListener;


/**
 *
 * @param itemClickListener used to trigger an item click event
 */
public PlayerListRecyclerAdapter(OnRecyclerItemClickListener itemClickListener){        
    mItemClickListener = itemClickListener;
    mInternalClickListener = new InternalClickListener();
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
   View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_item, parent, false);

    v.setOnClickListener(mInternalClickListener);

    ViewHolder viewHolder = new ViewHolder(v);
    return viewHolder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    // do your binding here
}

@Override
public int getItemCount() {
    return mDataSet.size();
}

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

    mRecyclerView = recyclerView;
}

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

    mRecyclerView = null;
}

public Data getItem(int position){
    return mDataset.get(position);
}
}

现在让我们看看如何从一个片段中整合这个:

public class TestFragment extends Fragment implements OnRecyclerItemClickListener<Data>{
   private RecyclerView mRecyclerView;

   @Override
   public void onItemClick(View view, int position, Data item) {
     // do something
   }

   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      return inflater.inflate(R.layout.test_fragment, container, false);
   }

   @Override
   public void onViewCreated(View view, Bundle savedInstanceState) {
      mRecyclerView = view.findViewById(idOfTheRecycler);
      mRecyclerView .setAdapter(new CustomRecyclerAdapter(this));
   }

其他回答

我喜欢这样,我正在用它

内部

public Adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)

Put

View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_image_and_text, parent, false);
v.setOnClickListener(new MyOnClickListener());

在任何你想要的地方创建这个类

class MyOnClickListener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
       int itemPosition = recyclerView.indexOfChild(v);
       Log.e("Clicked and Position is ",String.valueOf(itemPosition));
    }
}

我以前读过有一个更好的方法,但我喜欢这个方法,简单,不复杂。

RecyclerView是如何不同于Listview?

一个区别是有一个LayoutManager类和RecyclerView,通过它你可以像-一样管理你的RecyclerView

水平或垂直滚动线性layoutmanager GridLayout by GridLayoutManager 交错网格布局由StaggeredGridLayoutManager

就像水平滚动的RecyclerView-

LinearLayoutManager llm = new LinearLayoutManager(context);
llm.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerView.setLayoutManager(llm);

如果你想添加onClick()到项目的子视图,例如,项目中的按钮,我发现你可以很容易地在你自己的RecyclerView的onCreateViewHolder()中做到这一点。适配器就像这样:

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View v = LayoutInflater
                    .from(parent.getContext())
                    .inflate(R.layout.cell, null);

            Button btn = (Button) v.findViewById(R.id.btn);
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //do it
                }
            });

            return new MyViewHolder(v);
        }

我不知道这是不是一个好方法,但它很有效。如果有人有更好的想法,很高兴告诉我并纠正我的答案!:)

检查这一个,我已经实现了所有的事情与适当的方式

RecyclerViewHolder类

public class RecyclerViewHolder extends RecyclerView.ViewHolder  {

    //view holder is for girdview as we used in the listView
    public ImageView imageView,imageView2;
    public RecyclerViewHolder(View itemView) {
        super(itemView);
        this.imageView=(ImageView)itemView.findViewById(R.id.image);
    }

}

适配器

public class RecyclerView_Adapter extends RecyclerView.Adapter<RecyclerViewHolder> {

    //RecyclerView will extend to recayclerview Adapter
    private ArrayList<ModelClass> arrayList;
    private Context context;
    private static RecyclerViewClickListener itemListener;
    //constructor of the RecyclerView Adapter
    RecyclerView_Adapter(Context context,ArrayList<ModelClass> arrayList,RecyclerViewClickListener itemListener){
        this.context=context;
        this.arrayList=arrayList;
        this.itemListener=itemListener;
    }

    @Override
    public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //this method will inflate the custom layout and return as viewHolder
        LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
        ViewGroup mainGroup=(ViewGroup) layoutInflater.inflate(R.layout.single_item,parent,false);
        RecyclerViewHolder listHolder=new RecyclerViewHolder(mainGroup);

        return listHolder;
    }

    @Override
    public void onBindViewHolder(RecyclerViewHolder holder, final int position) {

        final ModelClass modelClass=arrayList.get(position);
        //holder
        RecyclerViewHolder mainHolder=(RecyclerViewHolder)holder;
        //convert the drawable image into bitmap
        Bitmap image= BitmapFactory.decodeResource(context.getResources(),modelClass.getImage());
        //set the image into imageView
        mainHolder.imageView.setImageBitmap(image);
        //to handle on click event when clicked on the recyclerview item and
        // get it through the RecyclerViewHolder class we have defined the views there
        mainHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //get the position of the image which is clicked
             itemListener.recyclerViewListClicked(v,position);
            }
        });

    }

    @Override
    public int getItemCount() {
        return (null!=arrayList?arrayList.size():0);
    }
}

的接口

public interface RecyclerViewClickListener {

    //this is method to handle the event when clicked on the image in Recyclerview
    public void recyclerViewListClicked(View v,int position);
}

//and to call this method in activity
RecyclerView_Adapter adapter=new RecyclerView_Adapter(Wallpaper.this,arrayList,this);
        recyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();


    @Override
    public void  recyclerViewListClicked(View v,int position){

        imageView.setImageResource(wallpaperImages[position]);

    }

在阅读了@MLProgrammer-CiM的回答后,以下是我的代码:

class NormalViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

    @Bind(R.id.card_item_normal)
    CardView cardView;

    public NormalViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
        cardView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if(v instanceof CardView) {
            // use getAdapterPosition() instead of getLayoutPosition()
            int itemPosition = getAdapterPosition();
            removeItem(itemPosition);
        }
    }
}