有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
From most of the answers above, they seem to be setting their onclicklisteners to individual items. However, the solution am about to offer is very simple but yet not intuitive to many. Many are forgetting that the other components are always in a parent component which is used to display items in the List or Recycler views. This solution is just about setting a single onclick listener to this parent view and the turn is played. The solution also includes a way to pass the position of the item being clicked on from the list or recycler view. Here, our main rootview is a CardView from the android support library. Here is sample code
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder> {
public static final String LOG_TAG = ListAdapter.class.getSimpleName();
private Cursor mDataset;
private Context mContext;
private ViewHolder mViewHolder;
// Provide a suitable constructor (depends on the kind of dataset)
public ListAdapter(Context context, Cursor Dataset) {
mDataset = Dataset;
mContext = context;
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_business_view, parent, false);
mViewHolder = new ViewHolder(v);
return mViewHolder;
}
public void setData(Cursor newdata) {
this.mDataset = newdata;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
//Bind data to other items here. To save time, i have ommited that.
//here is where we attach a click listerner for an item in the recycler list rather than for each element of a given item.
holder.card.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, " Just cliked item at position " + itemPosition, Toast.LENGTH_LONG).show();
}
});
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
if (null != mDataset) {
return mDataset.getCount();
}
return 0;
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder{
// each data item is just a string in this case
public final TextView mBusinesssName; // View for the business name
public final TextView mBusinessCategory; //View for the category name
public final ImageView businessImage; // View for the business category image Image
public final TextView mBusinessDistance; // View for the distance
public final CardView card;
public ViewHolder(View view) {
super(view);
mBusinesssName = (TextView) view.findViewById(R.id.list_item_name_textview);
mBusinessCategory = (TextView) view.findViewById(R.id.list_item_category_textview);
mBusinessDistance = (TextView) view.findViewById(R.id.list_item_dist_textview);
businessImage = (ImageView) view.findViewById(R.id.list_item_icon);
card = (CardView) view.findViewById(R.id.card_view);
}
}
}
其他回答
这对我来说很难在活动中有一个项目点击监听器,也有一个项目的单一视图的点击监听器,不会触发项目点击监听器。在玩了Jacob Tabak的回答后,我尊重他的回答,如果项目内没有其他触摸操作,就点击项目。
我有一个自定义OnClickListener接口,有一个项目点击事件,它持有从适配器点击的项目的视图和项目的位置。我在构造函数(或者它可以是setter)中呈现它的一个实例,并将它附加到视图持有者容器click listener。
我也有其他的点击监听器在适配器(可以在视图持有人),这将处理当前的视图点击从容器。
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
private ArrayList<String> mData;
private OnItemClickListener mOnItemClickListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
public MyRecyclerAdapter(ArrayList<String> itemsData,
OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
this.mData = itemsData;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View layoutView = LayoutInflater.from(mContext).inflate(
R.layout.list_item, parent, false);
final MyViewHolder viewHolder = new MyViewHolder(layoutView);
viewHolder.container.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mOnItemClickListener.onItemClick(v, viewHolder.getAdapterPosition());
}
});
viewHоlder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//do button click work here with
// mData.get( viewHolder.getAdapterPosition() );
}
});
return viewHolder;
}
@Override
public int getItemCount() {
return mData.size();
}}
在活动中,您需要通过传递OnItemClickListener实例来初始化适配器
public class FeedActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
.....
MyRecyclerAdapter adapter = new MyRecyclerAdapter(new ArrayList<String>(), new OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
///list item was clicked
}
});
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(mFeedsAdapter);
}
还有我的ViewHolder
public class MyViewHolder extends RecyclerView.ViewHolder {
public Button button;
public View container;
public MyViewHolder(View itemLayoutView) {
super(itemLayoutView);
container = itemLayoutView;
button = (Button) itemLayoutView.findViewById(R.id.button);
}}
这个作品。
public class ServiceListAdapter extends RecyclerView.Adapter<ServiceListAdapter.ViewHolder> {
private final Context mContext;
private List<ServiceListModel> categoryList;
private View.OnClickListener onClickListener;
public ServiceListAdapter(Context mContext, List<ServiceListModel> categoryList, View.OnClickListener onClickListener) {
this.categoryList = categoryList;
this.mContext = mContext;
this.onClickListener = onClickListener;
}
@Override
public ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
final RowServiceListBinding binding = DataBindingUtil.inflate(inflater, R.layout.row_service_list, parent, false);
return new ViewHolder(binding.getRoot(), binding);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.binding.rlService.setOnClickListener(onClickListener);
holder.binding.rlService.setTag(position);
}
@Override
public int getItemCount() {
return categoryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private final RowServiceListBinding binding;
public ViewHolder(final View view, final RowServiceListBinding binding) {
super(view);
this.binding = binding;
}
@UiThread
public void bind(final ServiceListModel mAddressModel) {
//this.binding.setAddress(mAddressModel);
}
}
}
在活动/片段中使用
ServiceListAdapter adapter = new ServiceListAdapter(context, serviceList, new View.OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.rlService:
int pos = (int) v.getTag();
serviceList.remove(position);
break;
}
}
});
这就是重用View的方法。OnClickListener:
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder>
implements View.OnClickListener
在ViewHoder中获取项目布局的父视图:
public class MyviewHolder extends RecyclerView.ViewHolder {
LinearLayout linearLayout;
public MyviewHolder(View itemView) {
super(itemView);
linearLayout = itemView.findViewById(R.id.linear_layout_item);
}
}
在onBindViewHolder中设置标签为位置:
@Override
public void onBindViewHolder(MyviewHolder holder, int position) {
holder.linearLayout.setTag(position);
holder.linearLayout.setOnClickListener(this);
}
在你的onClick实现中:
@Override
public void onClick(View v) {
int position = (int) v.getTag();
switch (v.getId()) {
case R.id.linear_layout_item:
// do some thing with position
break;
}
}
基于Jacob Tabak的回答(+1),我能够添加onLongClick监听器:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null) {
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
然后你可以这样使用它:
recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), recyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
// ...
}
@Override
public void onItemLongClick(View view, int position) {
// ...
}
}));
让我们看看如何在Jetpack / AndroidX中实现这一点
你需要像这样在viewmodel类中创建一个观察对象
private MutableLiveData<Integer> adapterItem = new MutableLiveData<>();
public MutableLiveData<Integer> getAdapterItem() {
return adapterItem;
}
public void setAdapterItem(int adapterItem) {
this.getAdapterItem().setValue(adapterItem);
}
然后在适配器类中,确保将viewmodel引用作为构造函数的参数传递,然后在vieholder上实现clicklistener
public MyViewHolder(@NonNull View itemView) {
super(itemView);
if(itemView != null){
itemView.setOnClickListener(v -> {
int adapterPosition = getAdapterPosition();
viewModel.setAdapterItem(adapterPosition);
});
};
}
然后从活动课上观察变化
viewModel.getAdapterItem().observe(this, position -> {
Log.w(TAG, "clicked: " + ridesArray.get(position));
});
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 碎片中的onCreateOptionsMenu
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?