有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。


当前回答

这个作品。

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;
            }
        }
    });

其他回答

这里有一个策略,它给出了一个类似于ListView实现的结果,因为你可以在活动或片段级别而不是适配器或ViewHolder级别定义侦听器。它还定义了一些抽象类,这些抽象类负责适配器和持有者的大量样板工作。

抽象类

首先,定义一个抽象Holder,它扩展了RecyclerView。并定义了一个泛型数据类型T,用于将数据绑定到视图。bindViews方法将由一个子类实现,用于将数据映射到视图。

public abstract class Holder<T> extends RecyclerView.ViewHolder {
    T data;

    public Holder(View itemView) {
        super(itemView);
    }

    public void bindData(T data){
        this.data = data;
        bindViews(data);
    }

    abstract protected void bindViews(T data);
}

同样,创建一个抽象适配器,扩展RecyclerView.Adapter<Holder<T>>。这定义了3个接口方法中的2个,子类将需要实现最后一个onViewHolderCreated方法。

public abstract class Adapter<T> extends RecyclerView.Adapter<Holder<T>> {
    List<T> list = new ArrayList<>();

    @Override
    public void onBindViewHolder(Holder<T> holder, int position) {
        holder.bindData(list.get(position));
    }

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

    public T getItem(int adapterPosition){
        return list.get(adapterPosition);
    }
}

具体类

现在创建一个扩展Holder的新具体类。该方法只需定义视图并处理绑定。这里我使用ButterKnife库,但请随意使用itemView.findViewById(…)方法代替。

public class PersonHolder extends Holder<Person>{
    @Bind(R.id.firstname) TextView firstname;
    @Bind(R.id.lastname) TextView lastname;

    public PersonHolder(View view){
        super(view);
        ButterKnife.bind(this, view);
    }

    @Override
    protected void bindViews(Person person) {
        firstname.setText(person.firstname);
        lastname.setText(person.lastname);
    }
}

最后,在持有RecyclerView的Activity或Fragment类中,你会有这样的代码:

// Create adapter, this happens in parent Activity or Fragment of RecyclerView
adapter = new Adapter<Person>(){
    @Override
    public PersonHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.layout_person_view, parent, false);

        PersonHolder holder = new PersonHolder(v);
        v.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                int itemPos = holder.getAdapterPosition();
                Person person = getItem(itemPos);

                // do something with person
                EventBus.getDefault().postSticky(new PersonClickedEvent(itemPos, person));
            }
        });

        return holder;
    }
};

下面是我的代码片段:

v.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        int newPosition = MainActivity.mRecyclerView.getChildAdapterPosition(v);
        Intent cardViewIntent = new Intent(c, MainActivityCards.class);
        cardViewIntent.putExtra("Position", newPosition);
        c.startActivity(cardViewIntent);
    }
});

v是onCreateViewHolder的视图 c为背景信息

根据Yigit Boyar的说法,在RecyclerView上注册点击的最好方法是在ViewHolder的创建中定义点击,而不是仅仅为onBindViewHolder绑定的每个项目创建一个新的onClickListener

例子:

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {
   val itemBinding = LayoutInflater.from(context).inflate(R.layout.my_layout, parent, false)

   val vh = MainViewHolder (itemBinding)
   vh.itemView.setOnClickListener {
       val pos = vh.adapterPosition
       if(pos != NO_POSITION){
           itemClickLister.onCocktailClick(myList[pos],pos)
       }
   }

   return vh
}

我的方式

活动课上:

    public class MyActivity extends AppCompatActivity implements EmployeeAdapter.ClickListener {
    ...
    @Override
    public void onClick(int position) { ... }
    ...
    }

适配器类:

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    ...
    @Override
    public void onBindViewHolder(){
         holder.textView1.setOnClickListener(v -> clickListener.onClick(position));
    }
    ...
    public interface ClickListener {
        void onClick(int position);
    }
    ...
    }

这个作品。

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;
            }
        }
    });