目前:
我正在Adapter
内的onBindViewHolder
中实现单击事件,但是我注意到这样做时适配器的位置会弄乱。我进行了一些研究,发现this,他说:
至于为什么在ViewHolder中而不是在onBindViewHolder()中更好,这是因为每个项目都调用了onBindViewHolder(),并且当您可以在ViewHolder构造函数中一次调用它时,设置单击侦听器是不必要的重复选项。
他引用的示例如下所示:
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnItemClickListener {
public MyViewHolder(View view) {
super(view);
view.setOnClickListener(this);
}
@Override
public void OnClick(View view) {
// Get the item clicked
// For this example, I'm assuming your data source is of type `List<MyObject>`
MyObject myObject = mDataSource.get(getAdapterPosition());
// Then you can do any actions on it, for example -
myObject.setChecked();
}
}
这对我来说很有意义,但是我的问题是我的
ImageButton
中有一个ViewHolder
,他的示例仅显示了如何处理ViewHolder
本身的单击事件。首先请看一下我的适配器当前的外观:public class MyAdapter extends Adapter<MyAdapter.ViewHolder> {
ArrayList<Bitmap> bitmapArrayList;
Context context;
LayoutInflater layoutInflater;
View myLayoutView;
ArrayList<PathModel> swingThumbPathList;
ArrayList<PathModel> swingVideoPathList = new ArrayList();
class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
TextView name;
CircularImageView image;
ImageButton viewholderOtions;
ViewHolder(View itemView) {
super(itemView);
}
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
this.myLayoutView = LayoutInflater.from(this.context).inflate(R.layout.single_item, parent, false);
return new ViewHolder(this.myLayoutView);
}
public void onBindViewHolder(ViewHolder myHolder, final int position) {
final ViewHolder holder = myHolder;
holder.viewholderOtions = (ImageButton) myLayoutView.findViewById(R.id.viewholderOptions);
holder.name = (TextView) this.myLayoutView.findViewById(R.id.name);
holder.image = (CircularImageView) this.myLayoutView.findViewById(R.id.image);
holder.name.setText(Model.getPath());
holder.image.setImageURI(Uri.parse(Model.getPath()));
holder.viewholderOtions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(holder.itemView.getContext(), "Options was clicked", Toast.LENGTH_LONG).show();
showPopupMenu(holder.viewholderOtions, position);
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String uri = holder.name.getText().toString();
Toast.makeText(holder.itemView.getContext(), uri, Toast.LENGTH_LONG).show();
}
});
}
private void showPopupMenu(final View view, final int position) {
// inflate menu
PopupMenu popup = new PopupMenu(view.getContext(), view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.popup_menu, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.delete:
//The correct position is being toasted
Toast.makeText(view.getContext(), position + "Delete", Toast.LENGTH_LONG).show();
return true;
case R.id.rename:
Toast.makeText(view.getContext(), "Rename", Toast.LENGTH_LONG).show();
return true;
default:
return true;
}
}
});
popup.show();
}
我的问题
如何处理
ViewHolder
本身和ImageButton
内部的ViewHolder
的单击事件? 最佳答案
我回头笑了一下这个问题,所以差不多两年后回答了我自己的问题。
使用问题中提供的相同逻辑,这就是如何将点击事件设置为视图本身,以及视图内部的元素,在viewholder而不是onBindViewHolder
public class MyAdapter extends Adapter<MyAdapter.ViewHolder> {
ArrayList<Bitmap> bitmapArrayList;
Context context;
LayoutInflater layoutInflater;
View myLayoutView;
ArrayList<PathModel> swingThumbPathList;
ArrayList<PathModel> swingVideoPathList = new ArrayList();
class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
TextView name;
CircularImageView image;
ImageButton viewholderOtions;
ViewHolder(View itemView) {
super(itemView);
viewholderOtions = itemView.findViewById(R.id.viewholderOptions);
videoName = itemView.findViewById(R.id.FilePath);
videoThumb = itemView.findViewById(R.id.VideoThumbnail);
//set OnClickListener's for the views we want click events for
itemView.setOnClickListener(this);
viewholderOtions.setOnClickListener(this);
videoThumb.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//get the tag that we have set in onBindViewHolder
int position = (int) v.getTag();
if (v == viewholderOtions) {
//viewholderOtions was selected, we can use the position above to see what item, as shown below:
Log.e("viewholderOtions at position =", String.valueOf(position);
}
if (v == itemView){
//itemView was selected, we can use the position above to see what item, as shown below:
Log.e("itemView at position =", String.valueOf(position);
}
if (v == videoThumbvideoThumb){
//itemView was selected, we can use the position above to see what item, as shown below:
Log.e("videoThumbvideoThumb at position =", String.valueOf(position);
}
}
}
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
this.myLayoutView = LayoutInflater.from(this.context).inflate(R.layout.single_item, parent, false);
return new ViewHolder(this.myLayoutView);
}
public void onBindViewHolder(ViewHolder myHolder, final int position) {
//set a tag so we can retrieve the position via the tag
myHolder.viewholderOtions.setTag(position);
//Set text to holder.name
holder.name.setText(Model.getPath());
//a better option to below is to use a library like picasso to handle the image loading
holder.image.setImageURI(Uri.parse(Model.getPath()));
}
}
但老实说,我仍然将点击事件设置在
onBindViewHolder
内,然后将以下内容设置为RecyclerView
-Activity
内的recyclerView.setHasFixedSize(true);
。如我的问题所述,通过这样做,职位不会变得混乱。关于android - 处理Adapter/ViewHolder中的单击事件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45546739/