没有内部类的Android RecyclerView项目OnClickListener

时间:2019-01-17 20:30:29

标签: android

我正在尝试在Android RecyclerView上实现列表项Click侦听器。我发现的大多数解决方案都添加了匿名内部类侦听器,以在onBindViewHolder方法中进行查看。因此,在滚动列表时,我们将不断创建新对象。我发现一些解决方案通过将ViewHolder作为标签添加到onCreateViewHolder中的项目视图来避免这种情况。这允许使用getAdapterPosition()获取当前位置,但是如何在活动或片段中没有引用的情况下获取当前位置的数据呢?我使用Loader加载数据并将其放入适配器,所以我不想在Fragment中保留对数据的引用。

我将对当前数据项的引用保存在ViewHolder中的onBindViewHolder对象中。

此解决方案正确且可接受吗?

非常感谢。

下面的代码示例

    private static class JobTypesAdapter extends RecyclerView.Adapter<JobTypesAdapter.JobTypesViewHolder> {
    private @NonNull List<JobType> jobTypes;
    private @Nullable View.OnClickListener onItemClickListener;

    JobTypesAdapter(@NonNull List<JobType> jobTypes, @Nullable View.OnClickListener onItemClickListener) {
        this.jobTypes = jobTypes;
        this.onItemClickListener = onItemClickListener;
    }

    void setData(@NonNull List<JobType> jobTypes) {
        this.jobTypes = jobTypes;
        notifyDataSetChanged();
    }

    @Override
    public @NonNull JobTypesViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        TextView tv = (TextView) LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.list_item_job_types, viewGroup, false);
        JobTypesViewHolder holder = new JobTypesViewHolder(tv);

        if (onItemClickListener != null) {
            tv.setTag(holder);
            tv.setOnClickListener(onItemClickListener);
        }
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull JobTypesViewHolder holder, int position) {
        JobType jobType = jobTypes.get(position);
        holder.setJobType(jobType);
        holder.txtJobTypeName.setText(jobType.getName());
    }

    @Override public void onViewRecycled(@NonNull JobTypesViewHolder holder) {
        super.onViewRecycled(holder);
        holder.setJobType(null);
    }

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

    static class JobTypesViewHolder extends RecyclerView.ViewHolder {
        TextView txtJobTypeName;
        private @Nullable JobType jobType;

        JobTypesViewHolder(TextView itemTextView) {
            super(itemTextView);
            txtJobTypeName = itemTextView;
        }

        @Nullable JobType getJobType() {
            return jobType;
        }

        void setJobType(@Nullable JobType jobType) {
            this.jobType = jobType;
        }
    }
}

这是我的onClickListener代码:

        jobTypesAdapter = new JobTypesAdapter(
            Collections.<JobType>emptyList(),
            new View.OnClickListener() {
                @Override public void onClick(View v) {
                    JobTypesAdapter.JobTypesViewHolder holder = (JobTypesAdapter.JobTypesViewHolder) v.getTag();
                    JobType jobType = holder.getJobType();
                    if (jobType != null) {
                        Log.d(TAG, jobType.getId() + "; " + jobType.getName());
                    }
                }
            });

1 个答案:

答案 0 :(得分:0)

您可以在holder类中实现点击侦听器:

...扩展RecyclerView.ViewHolder 实现View.OnClickListener

并在构造函数中分配侦听器。因此,接下来:

static class JobTypesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView txtJobTypeName;
    @Nullable 
    private JobType jobType;

    JobTypesViewHolder(TextView itemTextView) {
        super(itemTextView);
        txtJobTypeName = itemTextView;

        // Set click listener
        itemTextView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
      ...
      ...
    }

    @Nullable 
    JobType getJobType() {
        return jobType;
    }

    void setJobType(@Nullable JobType jobType) {
        this.jobType = jobType;
    }
}