Где я должен разместить setOnClickListener в адаптере RecyclerView

В учебниках в Интернете, где они устанавливают OnClickListener в адаптере RecyclerView, они определяют его двумя способами: либо внутри ViewHolder, либо внутри BindViewHolder.

Мой вопрос заключается в том, какой из них лучше. Пожалуйста, порекомендуйте любой другой подход, если он доступен.

1) внутри ViewHolder:

public static class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(View itemView) {
        super(itemView);
        tvSrc = (TextView) itemView.findViewById(R.id.tvSrc);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(v.getContext(), "inside viewholder position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
            }
        });
    }

2) внутри BindViewHolder

public void onBindViewHolder(DisplayTrainsAdapter.ViewHolder viewHolder, final int position) {

    viewHolder.tvSrc.setText(mDataset.get(position).strSrc);
    viewHolder.tvSrc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Toast.makeText(v.getContext(), "position = " + getItemId(position), Toast.LENGTH_SHORT).show();
        }
    });
}    

person Anudeep Samaiya    schedule 09.04.2015    source источник
comment
сделайте свой собственный ViewHolder реализацией View.OnClickListener, таким образом, вам не нужен собственный класс View.OnClickListener внутри ViewHolder   -  person pskink    schedule 09.04.2015


Ответы (5)


Оба варианта имеют свои плюсы и минусы.

Например, если кнопка нажата и вы хотите изменить текст своей кнопки, вам, вероятно, следует использовать вариант, в котором вы настраиваете прослушиватель onClick в ViewHolder. Помимо этой причины, это также делает ваш код чище.

Однако, если, скажем, при нажатии кнопки вы хотите изменить текст TextView в том же индексе/позиции, что и нажатая кнопка, вам нужно будет использовать параметр, в котором вы настраиваете прослушиватель onClick в методе onBindViewHolder. .

person Advait S    schedule 20.06.2015
comment
Это не имеет никакого смысла, вы можете делать и то, и другое в обоих случаях. - person alacret; 12.05.2017

Ваше решение номер 1 является лучшим, как вы предложили, поскольку это назначение не будет вызываться в Binding при каждом аннулировании, вызванном методами notify..(). Я знаю и другие решения, но вам нужно внедрить android.view.GestureDetector в свою деятельность.

Если вам нужны другие улучшения адаптера, взгляните на мой FlexibleAdapter https://github.com/davideas/FlexibleAdapter и смело внедряйте в свой проект.

person Davideas    schedule 04.05.2015

ИМХО: мне нравится номер 1.

Поскольку вы звоните в new ViewHolder(View), вы действительно настраиваете свой onClickListener перед фактическим отображением своего контента. Это хорошо, потому что к моменту вызова onBindView ваш onClickListener уже установлен в вашем представлении.

Я думаю, что это также более чистый код, чтобы сделать это в вашем конструкторе ViewHolder(View)

person kandroidj    schedule 09.04.2015

В ViewHolder() я думаю, так как вы определяете, что view хранится, что у него внутри и другие функции.

Но onBindViewHolder() вы говорите, что view, который определен в ViewHolder, будет иметь этот текст, это изображение...

person Jemshit Iskenderov    schedule 09.04.2015

Вы всегда должны проверять, имеет ли значение getAdapterPosition значение >= 0, потому что в редких случаях оно может быть равно -1 (NO_POSITION), что может привести к сбою в вашем приложении. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder#getadapterposition

person Юрий Чекалин    schedule 25.10.2018