Кнопка автоматически нажата, если я выберу одну кнопку в элементе RecyclerView - PullRequest
0 голосов
/ 22 октября 2018

В моем элементе RecyclerView есть кнопка наряду с другими видами.Я прячу кнопку, когда она нажата.Проблема в том, что, если я нажимаю кнопку на 1-м элементе, автоматически нажимается кнопка на 8-м элементе, если я нажимаю кнопку на 2-м элементе, автоматически нажимается кнопка на 9-м элементе и так далее.Как решить эту проблему?

Класс адаптера:

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

private List<Model> models;
Model model;
// public MyAdapterListener onClickListener;

SparseBooleanArray mStateButtons = new SparseBooleanArray();


public Adapter(List<Model> models){
    this.models = models;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_row, false);
    return  new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
    String question = models.get(position).getQues();
    final String optA = models.get(position).getOptA();
    final String optB = models.get(position).getOptB();
    final String optC = models.get(position).getOptC();
    final String optD = models.get(position).getOptD();
    final String answer = models.get(position).getAns();

    holder.question.setText(question);
    holder.optA.setText(optA);
    holder.optB.setText(optB);
    holder.optC.setText(optC);
    holder.optD.setText(optD);

    holder.options.setTag(position);
    holder.options.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            int radioButtonID = group.getCheckedRadioButtonId();
            int clickedPos = (Integer) group.getTag();

            models.get(clickedPos).setChecked(radioButtonID);


        }
    });
    holder.options.check(models.get(position).getChecked());

    final int currentPosition = holder.getAdapterPosition();
    final Button button = holder.seeAnswer;

    if(mStateButtons.valueAt(currentPosition)) {
        button.setVisibility(View.GONE);
    } else {
        button.setVisibility(View.VISIBLE);
    }

    holder.seeAnswer.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mStateButtons.put(position, true);
        }
    });

}

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

class ViewHolder extends RecyclerView.ViewHolder{

    TextView question;
    RadioButton optA, optB, optC, optD;
    Button seeAnswer;
    RadioGroup options;

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

        options = (RadioGroup) itemView.findViewById(R.id.rgMcqOptions);
        question = (TextView) itemView.findViewById(R.id.tvMcqQues);
        optA = (RadioButton) itemView.findViewById(R.id.rbOptA);
        optB = (RadioButton) itemView.findViewById(R.id.rbOptB);
        optC = (RadioButton) itemView.findViewById(R.id.rbOptC);
        optD = (RadioButton) itemView.findViewById(R.id.rbOptD);
        seeAnswer = (Button) itemView.findViewById(R.id.btnSeeAnswer);

    }

}
}

Ответы [ 3 ]

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

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

public class YourAdapter ... {

    // variable to save the state of buttons.
    // we use state true as hidden, false as visible
    SparseBooleanArray mStateButtons = new SparseBooleanArray();

    ...

    @Override
    public void onBindViewHolder(ContactsAdapter.ViewHolder viewHolder, int position) {
        final int currentPosition = viewHolder.getAdapterPosition();

        // assume this is your button
        Button button = viewHolder.yourButton;

        // set the previous state to button
        if(mStateButtons.valueAt(currentPosition)) {
           // state is true, so the button need to be hide.
           button.setVisibility(View.GONE);
        } else {
           // default value is valse, which is we set as visible.
           button.setVisibility(View.VISIBLE);
        }

        button.setOnClickListener(new View.OnClickListener() { 
            @Override
            public void onClick(View view) { 
              // save the state when clicked
              mStateButtons.put(currentPosition, true);  
            } 
        }); 
    }
}

ОБНОВЛЕНИЕ

Попробуйте переместить обработку кликов в ViewHolder, что-то вроде этого:

public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    ...
    Button seeAnswer;

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

        ...
        seeAnswer = (Button) itemView.findViewById(R.id.btnSeeAnswer);
        itemView.setOnClickListener(this);

    }

    // Handles the row being being clicked
    @Override
    public void onClick(View view) {
       mStateButtons.put(getAdapterPosition(), true);
       view.setVisibility(View.GONE);
    }
}

затем удалите button.setOnClickListener(new View.OnClickListener() в onBindViewHolder.

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

Вам нужен какой-то способ отслеживать, какие кнопки должны быть скрыты, а какие нет.Это ответственность вашего адаптера, поэтому вам нужно добавить некоторую форму массива, чтобы отслеживать состояние кнопок там.SparseBooleanArray - эффективный и подходящий вариант:

private SparseBooleanArray hideButtons = new SparseBooleanArray();

В onBindView необходимо обновить представление для текущего привязываемого элемента, включая обновление видимости кнопки:

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, final int position) {
    holder.seeAnswer.setVisibility( hideButtons.get(position, false) ? View.GONE : View.VISIBLE );
    ...
}

И, конечно же, вам нужно установить видимость и сохранить ее в SparseBooleanArray при нажатии кнопки.Поместить этот обработчик события в ViewHolder - хороший вариант:

class ViewHolder extends RecyclerView.ViewHolder{
    Button seeAnswer;
    ...

    ViewHolder(View itemView) {
        super(itemView);

        seeAnswer = (Button) itemView.findViewById(R.id.btnSeeAnswer);

        seeAnswer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                seeAnswer.setVisibility(View.GONE);
                hideButtons.put(getAdapterPosition(), true);
            }
        });

        ...
    }

}

Это проверенное и проверенное решение, поэтому, если вы будете следовать этому, но оно все равно не будет работать, причина вашей проблемыгде-то еще.

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

Кажется, проблема в том, что вы неправильно инициализируете состояние Button.Ячейки в RecyclerView используются повторно, когда они появляются или прячутся на экране.Это означает, что если вы скрываете 1-ю позицию, а затем этот вид повторно используется для создания 8-го, Button сохраняет свое состояние, в этом случае INVISIBLE

Попробуйте присвоить значение всем случаям или инициироватьзначение VISIBLE.

Надеюсь, это поможет.

...