RecyclerView onClickListener Настройка производительности - PullRequest
0 голосов
/ 26 октября 2018

, поэтому я впервые попытался реализовать onClickListener для моего RecyclerView, и мне было интересно, стоит ли делать то, что я делал. В моем приложении у меня есть разные виды Recycler, и мне не нужно одновременно использовать onClickListeners и onLongClickListeners в большинстве из них, поэтому я хотел сделать это так, чтобы мне не пришлось реализовывать их оба в мой .setOnItemClickListener. Я в основном проверяю, какой onClickListener настроен в режиме enum, а затем в соответствии с этим я устанавливаю своих слушателей в onCreateViewHolder. Есть ли смысл делать это? Или мне просто реализовать обоих слушателей и не делать то, что я делал в своем коде?

public class FreindRecyclerViewAdapter extends RecyclerView.Adapter<FreindRecyclerViewAdapter.MyViewHolder> {

    private ClickListener clickListener ;
    private LongClickListener longClickListener;

    private Context context;
    private List<String> friends;
    private ListenerMode mode;

    public enum ListenerMode {NullMode, ShortClick, LongClick}

    public interface ClickListener {

        void onItemClick(int position, View v);

    }

    public interface LongClickListener {

        void onItemLongClick(int position, View v);

    }

    public void setOnItemClickListener(ClickListener clickListener) {
        this.clickListener = clickListener;
        mode = ListenerMode.ShortClick;
    }

    public void setOnLongItemClickListener(LongClickListener longItemClickListener) {
        this.longClickListener = longItemClickListener;
        mode = ListenerMode.LongClick;
    }

    public FreindRecyclerViewAdapter (Context context, List<String> friends) {

        this.context = context;
        this.friends = friends;
        this.mode = ListenerMode.NullMode;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view;
        view = LayoutInflater.from(context).inflate(R.layout.friend_item, viewGroup, false);
        final MyViewHolder myViewHolder = new MyViewHolder(view);

        if(mode == ListenerMode.ShortClick) {
            myViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    clickListener.onItemClick(myViewHolder.getAdapterPosition(), view);
                }
            });
        } else if (mode == ListenerMode.LongClick) {

            myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {

                    longClickListener.onItemLongClick(myViewHolder.getAdapterPosition(), view);

                    return true;
                }
            });

        }



        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int position) {

        myViewHolder.friendName.setText(friends.get(position));


    }

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

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        private TextView friendName;

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

            friendName= itemView.findViewById(R.id.friendName_ID);

        }

    }

}

РЕДАКТИРОВАТЬ : Теперь, когда я думаю об этом, я даже не знаю, почему это работает, например, когда я настраиваю свой RecyclerView, адаптер и все в своем коде ниже, я сначала говорю адаптеру о списке, который я хочу показать на экране в его конструкторе recyclerViewAdapter = new FreindRecyclerViewAdapter(this, friends);, так что это когда onCreateViewHolder вызывается для моих представлений. Поэтому теперь, когда все создано (ViewHolders), я вызываю функцию для настройки OnClickListener, который в моем коде добавляет разных слушателей в соответствии с установленным mode, и эти слушатели добавляются в onCreateViewHolder, который уже был вызвал, так почему RecyclerViewAdapter (и как он узнает) снова вызывает onCreateViewHolder, чтобы добавить слушателей?

friends = new ArrayList<>();

        friends.add("Josh");
        friends.add("Mike");
        friends.add("Ashley");
        friends.add("Jess");


        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        recyclerView = findViewById(R.id.recyclerViewFriend_ID);
        recyclerViewAdapter = new FreindRecyclerViewAdapter(this, friends);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(recyclerViewAdapter);

        DividerItemDecoration itemDecor = new DividerItemDecoration(this, linearLayoutManager.getOrientation());
        recyclerView.addItemDecoration(itemDecor);



        recyclerViewAdapter.setOnLongItemClickListener(new FreindRecyclerViewAdapter.LongClickListener() {
            @Override
            public void onItemLongClick(int position, View v) {
                Toast.makeText(FriendActivity.this, "Long Click. Position:" + Integer.toString(position), Toast.LENGTH_SHORT).show();
            }
        });

1 Ответ

0 голосов
/ 27 октября 2018

Это нормально, но может быть и лучше.

1) Вы создаете прослушиватель щелчков и слушатель длинных щелчков для каждой позиции

Вам не нужно создавать слушателя для каждой позиции, как вы делаете здесь:

myViewHolder.itemView.setOnClickListener(new View.OnClickListener() ...

and

myViewHolder.itemView.setOnLongClickListener(new View.OnLongClickListener() ...

Поскольку они выполняют очень похожее действие, вы можете создать только один щелчок и прослушивание longclick и делиться им со всеми представлениями. Для этого переместите itemView.setOnClickListener() и itemView.setOnLongClickListener() в класс ViewHolder.

Вам также необходимо сохранить позицию в ViewHolder. Таким образом, они смогут хранить свою позицию.

2) Вам не нужно создавать перечисление

Вам не нужно создавать перечисление для проверки текущего режима (щелчок или длительный щелчок). Вместо этого вы можете просто проверить, равны ли переменные нулю, например.

В конце концов, вы можете получить такой код:

public class FreindRecyclerViewAdapter extends RecyclerView.Adapter<FreindRecyclerViewAdapter.MyViewHolder> {

    private ClickListener clickListener ;
    private LongClickListener longClickListener;

    private Context context;
    private List<String> friends;

    public interface ClickListener {
        void onItemClick(int position, View v);
    }

    public interface LongClickListener {
        void onItemLongClick(int position, View v);
    }

    public void setOnItemClickListener(ClickListener clickListener) {
        this.clickListener = clickListener;
    }

    public void setOnLongItemClickListener(LongClickListener longItemClickListener) {
        this.longClickListener = longItemClickListener;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view;
        view = LayoutInflater.from(context).inflate(R.layout.friend_item, viewGroup, false);
        return new MyViewHolder(view, i, clickListener, longClickListener);;
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int position) {
        myViewHolder.friendName.setText(friends.get(position));
    }

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

    public class MyViewHolder extends RecyclerView.ViewHolder implements
            View.OnLongClickListener, View.OnClickListener {

        private TextView friendName;
        private int position;

        public MyViewHolder(View itemView, int position) {
            super(itemView);
            friendName = itemView.findViewById(R.id.friendName_ID);
            this.position = position;
            if (clickListener != null) {
                itemView.setOnClickListener(this);
            }
            if (longClickListener != null) {
                itemView.setOnLongClickListener(this);
            }
        }

        @Override
        public void onClick(View view) {
            if (clickListener != null) {
                clickListener.onItemClick(position, view);
            }
        }

        @Override
        public boolean onLongClick(View view) {
            if (longClickListener != null) {
                longClickListener.onItemLongClick(position, view);
                return true;
            } else {
                return false;
            }
        }
    }
}
  • Обратите внимание, что теперь каждый держатель представления знает свою собственную позицию
  • Держатель вида реализует обычные View.OnClickListener и View.LongClickListener. Таким образом, вам не нужно создавать экземпляр нового слушателя для каждой позиции.
  • Если вы хотите включить клик, позвоните FreindRecyclerViewAdapter.setOnItemClickListener(object);
  • Если вы хотите включить длительный клик, позвоните FreindRecyclerViewAdapter.setOnLongItemClickListener(object);
  • Если вы хотите отключить любой из них, не вызывайте методы выше или просто вызывайте их, передавая null в качестве параметра. Если вы проверите код в MyViewHolder, вы увидите, что любое действие выполняется, когда эти слушатели имеют значение null

Надеюсь, я смогу помочь и поделиться еще несколькими способами для достижения того, что вы хотите !!!

...