我很困惑这里的点击处理是如何工作的。为什么我们将 this
从主 Activity 转移到 GreenAdapter
构造函数,并将 ListItemClickListener mOnClickListener
设置为 this
。
RecyclerView 中的点击处理究竟如何工作。
NumberViewHolder 在此仅创建或调用 10 次,并在其余 100 个项目 View 中回收。那么 onClick(View v) 是如何区分 100 种不同的列表项 View 的呢?我们只在创建的 10 个项目 View 上设置 itemView.setOnClickListener。
public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {
private static final String TAG = GreenAdapter.class.getSimpleName();
final private ListItemClickListener mOnClickListener;
private static int viewHolderCount;
private int mNumberItems;
public interface ListItemClickListener {
void onListItemClick(int clickedItemIndex);
}
public GreenAdapter(int numberOfItems, ListItemClickListener listener) {
mNumberItems = numberOfItems;
mOnClickListener = listener;
viewHolderCount = 0;
}
@Override
public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.number_list_item;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NumberViewHolder viewHolder = new NumberViewHolder(view);
viewHolder.viewHolderIndex.setText("ViewHolder index: " + viewHolderCount);
int backgroundColorForViewHolder = ColorUtils
.getViewHolderBackgroundColorFromInstance(context, viewHolderCount);
viewHolder.itemView.setBackgroundColor(backgroundColorForViewHolder);
viewHolderCount++;
Log.d(TAG, "onCreateViewHolder: number of ViewHolders created: "
+ viewHolderCount);
return viewHolder;
}
@Override
public void onBindViewHolder(NumberViewHolder holder, int position) {
Log.d(TAG, "#" + position);
holder.bind(position);
}
@Override
public int getItemCount() {
return mNumberItems;
}
class NumberViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
// Will display the position in the list, ie 0 through getItemCount() - 1
TextView listItemNumberView;
// Will display which ViewHolder is displaying this data
TextView viewHolderIndex;
public NumberViewHolder(View itemView) {
super(itemView);
listItemNumberView = (TextView) itemView.findViewById(R.id.tv_item_number);
viewHolderIndex = (TextView) itemView.findViewById(R.id.tv_view_holder_instance);
itemView.setOnClickListener(this);
}
void bind(int listIndex) {
listItemNumberView.setText(String.valueOf(listIndex));
}
@Override
public void onClick(View v) {
int clickedPosition = getAdapterPosition();
mOnClickListener.onListItemClick(clickedPosition);
}
}
}
在 mainActivity 中,我有
public class MainActivity extends AppCompatActivity
implements GreenAdapter.ListItemClickListener {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNumbersList = (RecyclerView) findViewById(R.id.rv_numbers);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
mNumbersList.setLayoutManager(layoutManager);
mNumbersList.setHasFixedSize(true);
mAdapter = new GreenAdapter(NUM_LIST_ITEMS, this);
mNumbersList.setAdapter(mAdapter);
}
@Override
public void onListItemClick(int clickedItemIndex) {
if (mToast != null) {
mToast.cancel();
}
String toastMessage = "Item #" + clickedItemIndex + " clicked.";
mToast = Toast.makeText(this, toastMessage, Toast.LENGTH_LONG);
mToast.show();
}
...
}
最佳答案
ViewHolder
的任务是维护您的不同 View (本例中为 100 个)可用。这对于设备性能来说是疯狂的,因此 RecyclerView
会“回收”它们 10 x 10(或其他)。对于这 10 个不同元素中的每一个都会调用 NumberViewHolder
,因此系统知道当您单击它时引用哪个元素。
这就是为什么要在其上设置 itemView.setOnClickListener(this);
的原因,因为每个 View
都必须有自己的。
RecyclerView.ViewHolder
A ViewHolder describes an item view and metadata about its place within the RecyclerView.
因此,您要为 View
设置的所有内容都必须在那里定义,然后 RecyclerView
将完成将其应用于所有项目的“肮脏工作” .
编辑:这里有一个我一年多前就同一件事问过的类似问题:Click an ImageButton which belongs to a CardView inside a RecyclerView
关于java - recyclerView 点击处理中的这是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45101332/