有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
RecyclerView没有OnClickListener,必须自己实现它。
我喜欢在适配器中添加OnItemClickListener接口,当您从ViewHolder中单击项目视图时调用onClick方法。因此,管理项目点击的职责不在ViewHolder和Adapter的范围内。将决定做什么的活动或片段
为监听器和监听器对象添加接口。
public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
...
private static OnItemClickListener onItemClickListener;
...
public static interface OnItemClickListener {
public void onItemClick(View view, int position);
}
...
}
我们捕获项目根视图的单击,以及当回调触发时适配器上的onClick侦听器调用。
public class ItemsAdapter extends RecyclerView.Adapter<ItemsAdapter.ViewHolder> {
...
private static OnItemClickListener onItemClickListener;
...
public static interface OnItemClickListener {
public void onItemClick(View view, int position);
}
...
public static class ViewHolder extends RecyclerView.ViewHolder {
public ImageView imageView;
public ViewHolder(View itemRootView) {
super(itemRootView);
imageView = (ImageView) itemRootView.findViewById(R.id.itemImage);
itemRootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int position = ViewHolder.super.getAdapterPosition();
onItemClickListener.onItemClick(view,position);
}
});
}
}
}
由于活动或片段,片段在我们的情况下,我们分配一个监听器到适配器和onClick回调,我们将获得选定的项目的位置和打开一个详细的活动项目。
public class ItemsFragment extends Fragment {
...
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
((ItemsAdapter) adapter).setOnItemClickListener(new ItemsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
//Do something when an item has been clicked
}
});
...
}
...
}
其他回答
对我来说,最干净的方法就是这个。
适配器的构造函数
private class EnvironmentTypeRecyclerViewAdapter extends RecyclerView.Adapter<EnvironmentTypeRecyclerViewAdapter.ViewHolder>
{
private final EnvironmentTypeRecyclerViewAdapterListener mEnvironmentTypeRecyclerViewAdapterListener;
private List<Environment> mEnvironmentsData;
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
public ViewHolder(View v)
{
super(v);
v.setOnClickListener(this);
}
@Override
public void onClick(View v)
{
Environment environment = mEnvironmentsData.get(getAdapterPosition());
if (mEnvironmentTypeRecyclerViewAdapterListener != null && environment != null) {
mEnvironmentTypeRecyclerViewAdapterListener.onListItemSelected(environment);
}
}
public EnvironmentTypeRecyclerViewAdapter(List<SmallCellEnvironment> environments, EnvironmentTypeRecyclerViewAdapterListener environmentTypeRecyclerViewAdapterListener)
{
mEnvironmentTypeRecyclerViewAdapterListener = environmentTypeRecyclerViewAdapterListener;
mEnvironmentsData = environments;
}
}
链接接口
private interface EnvironmentTypeRecyclerViewAdapterListener
{
void onListItemSelected(Environment environment);
}
这对我来说很管用。将OnClickListener附加到onBindView。我真的不知道这是否会影响性能,但它似乎用很少的代码就能很好地工作。
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "Recycle Click" + position, Toast.LENGTH_SHORT).show();
}
});
}
由于API已经发生了根本性的变化,如果你要为每个项目创建一个OnClickListener,这不会让我感到惊讶。不过也没那么麻烦。在你的RecyclerView的实现中。适配器<MyViewHolder>,你应该有:
private final OnClickListener mOnClickListener = new MyOnClickListener();
@Override
public MyViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.myview, parent, false);
view.setOnClickListener(mOnClickListener);
return new MyViewHolder(view);
}
onClick方法:
@Override
public void onClick(final View view) {
int itemPosition = mRecyclerView.getChildLayoutPosition(view);
String item = mList.get(itemPosition);
Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
}
如果你想在个别项目上捕捉点击事件,那么只需在ViewHolder类中实现OnClickListener,然后在个别视图或整个itemView上设置点击侦听器。
下面的例子说明了同样的情况
public class ContactViewHolder extends RecyclerView.ViewHolder implements OnClickListener
{
TextView txt_title,txt_name,txt_email;
public ContactViewHolder(View itemView)
{
super(itemView);
txt_title = (TextView)itemView.findViewById(R.id.txt_title);
txt_name = (TextView)itemView.findViewById(R.id.txt_name);
txt_email = (TextView)itemView.findViewById(R.id.txt_email);
txt_name.setOnClickListener(this);
txt_email.setOnClickListener(this);
itemView.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(v == itemView)
{
Toast.makeText(RecyclerDemoActivity.this, "Visiting Card Clicked is ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
}
if(v == txt_name)
{
Toast.makeText(RecyclerDemoActivity.this, "Name ==>"+txt_name.getText(), Toast.LENGTH_SHORT).show();
}
if(v == txt_email)
{
Toast.makeText(RecyclerDemoActivity.this, "Email ==>"+txt_email.getText(), Toast.LENGTH_SHORT).show();
}
}
}
}
让我们看看如何在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++ ?