java - recyclerView 点击处理中的这是什么?

标签 java android

我很困惑这里的点击处理是如何工作的。为什么我们将 this 从主 Activity 转移到 GreenAdapter 构造函数,并将 ListItemClickListener mOnClickListener 设置为 this

RecyclerView 中的点击处理究竟如何工作。

NumberViewHolder 在此仅创建或调用 10 次,并在其余 100 个项目 View 中回收。那么 onClick(View v) 是如何区分 100 种不同的列表项 View 的呢?我们只在创建的 10 个项目 View 上设置 itemView.setOnClickListener。

public class GreenAdapter extends RecyclerView.Adapter<GreenAdapter.NumberViewHolder> {

    private static final String TAG = GreenAdapter.class.getSimpleName();


    final private ListItemClickListener mOnClickListener;


    private static int viewHolderCount;

    private int mNumberItems;


    public interface ListItemClickListener {
        void onListItemClick(int clickedItemIndex);
    }


    public GreenAdapter(int numberOfItems, ListItemClickListener listener) {
        mNumberItems = numberOfItems;
        mOnClickListener = listener;
        viewHolderCount = 0;
    }


    @Override
    public NumberViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        Context context = viewGroup.getContext();
        int layoutIdForListItem = R.layout.number_list_item;
        LayoutInflater inflater = LayoutInflater.from(context);
        boolean shouldAttachToParentImmediately = false;

        View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
        NumberViewHolder viewHolder = new NumberViewHolder(view);

        viewHolder.viewHolderIndex.setText("ViewHolder index: " + viewHolderCount);

        int backgroundColorForViewHolder = ColorUtils
                .getViewHolderBackgroundColorFromInstance(context, viewHolderCount);
        viewHolder.itemView.setBackgroundColor(backgroundColorForViewHolder);

        viewHolderCount++;
        Log.d(TAG, "onCreateViewHolder: number of ViewHolders created: "
                + viewHolderCount);
        return viewHolder;
    }


    @Override
    public void onBindViewHolder(NumberViewHolder holder, int position) {
        Log.d(TAG, "#" + position);
        holder.bind(position);
    }


    @Override
    public int getItemCount() {
        return mNumberItems;
    }


    class NumberViewHolder extends RecyclerView.ViewHolder
        implements View.OnClickListener {

        // Will display the position in the list, ie 0 through getItemCount() - 1
        TextView listItemNumberView;
        // Will display which ViewHolder is displaying this data
        TextView viewHolderIndex;


        public NumberViewHolder(View itemView) {
            super(itemView);

            listItemNumberView = (TextView) itemView.findViewById(R.id.tv_item_number);
            viewHolderIndex = (TextView) itemView.findViewById(R.id.tv_view_holder_instance);

            itemView.setOnClickListener(this);
        }


        void bind(int listIndex) {
            listItemNumberView.setText(String.valueOf(listIndex));
        }



        @Override
        public void onClick(View v) {
            int clickedPosition = getAdapterPosition();
            mOnClickListener.onListItemClick(clickedPosition);
        }
    }
}

在 mainActivity 中,我有

public class MainActivity extends AppCompatActivity
        implements GreenAdapter.ListItemClickListener {
...
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        mNumbersList = (RecyclerView) findViewById(R.id.rv_numbers);


        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        mNumbersList.setLayoutManager(layoutManager);


        mNumbersList.setHasFixedSize(true);


        mAdapter = new GreenAdapter(NUM_LIST_ITEMS, this);
        mNumbersList.setAdapter(mAdapter);
    }
 @Override
    public void onListItemClick(int clickedItemIndex) {

        if (mToast != null) {
            mToast.cancel();
        }


        String toastMessage = "Item #" + clickedItemIndex + " clicked.";
        mToast = Toast.makeText(this, toastMessage, Toast.LENGTH_LONG);

        mToast.show();
    }
...
}

最佳答案

ViewHolder 的任务是维护您的不同 View (本例中为 100 个)可用。这对于设备性能来说是疯狂的,因此 RecyclerView 会“回收”它们 10 x 10(或其他)。对于这 10 个不同元素中的每一个都会调用 NumberViewHolder,因此系统知道当您单击它时引用哪个元素。

这就是为什么要在其上设置 itemView.setOnClickListener(this); 的原因,因为每个 View 都必须有自己的。

来自Android Developers Guide :

RecyclerView.ViewHolder

A ViewHolder describes an item view and metadata about its place within the RecyclerView.

因此,您要为 View 设置的所有内容都必须在那里定义,然后 RecyclerView 将完成将其应用于所有项目的“肮脏工作” .

编辑:这里有一个我一年多前就同一件事问过的类似问题:Click an ImageButton which belongs to a CardView inside a RecyclerView

关于java - recyclerView 点击处理中的这是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45101332/

相关文章:

java - 修改或生成Android resources.arsc和编译 list

java - Android sqlite邻接模型

java - 我们可以用JMeter做哪些类型的项目测试

java - Android Wear 上的奇怪渲染问题

java - POJO JAXB 注释未转换为 XML

android - OpenGL 与 OpenGL ES(GLchar 等)

java - 为什么 JAVA 中会忽略 ASCII SUB (\u001a)?

java - 使用 Java 更新 MongoDB 中的嵌入文档

android - ActionBar 总是用里面的图标展开 SearchView

android - Eclipse - 在开发时使用组合键 CTRL + Space 显示 android 类?