【问题标题】:What is this in a recyclerView click handling?recyclerView 点击处理中这是什么?
【发布时间】:2017-07-14 11:00:25
【问题描述】:

我很困惑点击处理在这里的工作方式。为什么我们将 this 从 main Activity 变为 GreenAdapter 构造函数并将 ListItemClickListener mOnClickListener 设置为 this

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

NumberViewHolder 仅在此处创建或调用 10 次,并在其余 100 个项目视图中循环使用。那么 onClick(View v) 如何区分这 100 个不同的列表项视图。我们只在创建的 10 个项目视图上设置 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();
    }
...
}

【问题讨论】:

  • 这里this关键字用于提及实现的接口。实际上,它指的是一个 MainActivity,它是一个 ListItemClickListener。这是java基础。
  • 好的,谢谢。 NumberViewHolder 仅在此处创建或调用 10 次,并为其余的项目视图回收。那么onClick(View v)是如何区分这100个不同的列表项视图
  • 你为什么要我们解释别人的代码/你为什么不问写它的人?
  • 因为我在网上学习。所以我很难理解

标签: java android


【解决方案1】:

ViewHolder 的任务是保持您的不同视图(在本例中为 100 个)可用。这对设备性能来说太疯狂了,所以RecyclerView '回收'它们 10 x 10 (或其他)。 NumberViewHolder 会为这 10 个不同的元素中的每一个调用,因此系统会在您单击它时知道引用了哪个元素。

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

来自Android Developers Guide

RecyclerView.ViewHolder

ViewHolder 描述项目视图和有关其位置的元数据 在 RecyclerView 中。

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

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

【讨论】:

  • 好的,谢谢,我又得到了一份 qn。当我调用 super(itemView) 时,RecyclerView.ViewHolder 类的最终 itemView 变量正在初始化为我们在 super 调用中传递的 itemView,对吧?
  • 因为您正在扩展另一个类的功能(在这种情况下为RecyclerView.ViewHolder),所以您必须首先“执行”父类方法,然后在您的自定义ViewHolder 中执行任何您想要的操作。所以或多或少你是对的。
猜你喜欢
  • 2023-03-22
  • 2020-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
相关资源
最近更新 更多