Событие в элементах RecyclerView влияет на несколько строк одновременно, а не на одну конкретную строку - PullRequest
0 голосов
/ 30 апреля 2019

Чтобы подвести итог моего приложения, у меня есть RecyclerView, размер которого является динамическим и относительно переменной ViewModel (когда эта переменная изменяется, список элементов RecyclerView увеличивается или уменьшается соответственно).

В каждом ряду есть пара кнопок.Каждая из этих кнопок имеет OnClickListener.(При нажатии кнопка исчезает).

Проблема: При нажатии кнопки исчезает не только эта кнопка, но также исчезает каждый дополнительный кратный 7 (по индексу).

Например: вы нажимаете кнопку в строке 1, и то же самое происходит в строках 8, 15 и 22, даже если вы нажали только строку 1.

Я сейчас прохожупрослушиватель через метод onViewCreated моего фрагмента к закрытой переменной прослушивателя в адаптере (набор слушателей в конструкторе).

Я покажу соответствующие биты моего фрагмента и адаптера:

Фрагмент:

public class MyFragment extends Fragment {
    private MyModel model;
    private ArrayList<Data> dataList;
    private int numberOfDataItems;

    private RecyclerView content;
    private RecycleAdapter adapter;

    private View.OnClickListener onItemClickLIstener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            RecyclerAdapter.ViewHolder viewHolder = (RecyclerAdapter.ViewHolder) view.getTag();

            // This is the buggy bit
            viewHolder.myButton.setVisibility(View.GONE);

            int position = viewHolder.getAdapterPosition();
            Data data = dataList.get(position);
            // TODO: eventually do some logic here with the data
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        content = view.findViewById(R.id.content);
        model.createDataList(numberOfDataItems);
        dataList = model.getDataList();

        adapter = new RecycleAdapter(dataList);
        content.setAdapter(adapter);
        content.setLayoutManager(new LinearLayoutManager(getContext()));

        adapter.setOnItemClickListener(onItemClickListener);
    }
}

Адаптер:

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {
    private List<Data> dataList;
    private View.OnClickListener onItemClickListener;

    public class ViewHolder extends RecyclerView.ViewHolder {
        public Button myButton;

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

            myButton = itemView.findViewById(R.id.myButton);
            myButton.setTag(this);
            myButton.setOnClickListener(onItemClickListener);
        }
    }

    @Override
    public RecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context conext = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        View DataView = inflater.inflate(R.layout.data_layout, parent, false);
        return new ViewHolder(dataView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecycleAdapter.ViewHolder viewHolder, int position) {
        Data data = dataList.get(position);
        // Do stuff with data

        myButton.setText(data);
    }

    public void setOnItemClickListener(View.OnClickListener itemClickListener) {
        onItemClickListener = itemClickListener;
    }
}

Ответы [ 2 ]

2 голосов
/ 30 апреля 2019

Вы передаете слушателю onClick viewHolder, делая это

   myButton.setTag(this);  // this = viewHolder

ViewHolder является перерабатываемым представлением.Таким образом, вы не можете рассматривать это представление как уникальное представление элемента.Помните, что viewHolder создается для повторного использования другими элементами.Вот почему вы видите свое действие, отраженное в других предметах.

Решение:

Установите для своего тега не viewHolder, а позицию товара.Затем в вашей структуре Data вы должны добавить переменные, чтобы запомнить, какие кнопки должны отображаться или нет.

class Data {
    ...
    String text;
    boolean btnVisible;
}

В View.OnClickListener вы должны установить значения этих переменных.

private View.OnClickListener onItemClickLIstener = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        int position =  (int)view.getTag();
        Data data = dataList.get(position);
        data.btnVisible = false;
        adapter.notifyDataSetChanged();
        // TODO: eventually do some logic here with the data
    }
}

Затем в onBindViewHolder необходимо установить текст кнопки и состояние видимости кнопки в зависимости от переменных в структуре Data.

@Override
public void onBindViewHolder(@NonNull RecycleAdapter.ViewHolder viewHolder, int position) {
    Data data = dataList.get(position);
    // Do stuff with data

    myButton.setText(data.text);
    myButton.setVisibility(?data.btnVisible:VISIBLE:GONE);
}
2 голосов
/ 30 апреля 2019

пожалуйста, используйте ниже, чтобы получить точную позицию, SetTag (); чтобы просмотреть, а затем нажать на кнопку, получить значение этого тега с помощью getTag (); за идеальное положение.

    myViewHolder.ivVoiceThumb.setTag(pos);
    myViewHolder.ivVoiceThumb.setOnClickListener(view -> {
        int getPos = (int)view.getTag();
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...