Проблема с утилизатором-адаптером на клике - PullRequest
1 голос
/ 23 октября 2019

У меня проблема с методом onClick в моем адаптере утилизатора.

Я передаю свой адаптер из фрагмента, а затем в адаптере я получаю всю информацию, необходимую мне из firebase, включая информацию о пользователях и кнопки "присоединиться", которые былиуже нажал (я установил красный фон для этой кнопки). Все работает нормально, пока я не нажму на кнопку «присоединиться», которая раньше не нажималась. Цвет кнопки меняется (работает нормально и сохраняет информацию в firebase с помощью метода joinEvent), но иногда меняется и цвет соседних кнопок. Я исследовал проблему, но у меня ничего не работает. Я попытался назначить позицию для методов (joinEvent, checkIfInterested, checkIfAccepted) вместо держателей, но это не работает. Буду признателен за любую помощь! Это мой адаптер:

public class SuggestionHomeAdapter extends RecyclerView.Adapter<SuggestionHomeAdapter.ViewHolder> {
private Context mContext;
private List<Suggestion> mSuggestion;
private FirebaseUser fuser;
int index = -1;


public SuggestionHomeAdapter(Context mContext, List<Suggestion> mSuggestion) {
    this.mSuggestion = mSuggestion;
    this.mContext = mContext;
}

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

@Override
public void onBindViewHolder(@NonNull final SuggestionHomeAdapter.ViewHolder holder, final int position) {

    final Suggestion suggestion = mSuggestion.get(position);
    fuser = FirebaseAuth.getInstance().getCurrentUser();


    holder.title.setText(suggestion.getTitle());
    holder.description.setText(suggestion.getDescription());
    holder.join.setBackgroundColor(0xF0DC82);
    getUserInfo(holder.username, holder.profile_image, suggestion.getSpublisher());

    checkIfInterested(holder.join, suggestion.getSid(), fuser.getUid());
    checkIfAccepted(holder.join, suggestion.getSid(), fuser.getUid());

    ColorDrawable buttonColor = (ColorDrawable) holder.join.getBackground();
    final int colorId = buttonColor.getColor();

    holder.join.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(colorId != 0xFFFF0000 && colorId != 0xff00ff00){
                joinEvent(fuser.getUid(), suggestion.getSid(), suggestion.getSpublisher());
            notifyItemChanged(position);}
        }
    });
}

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

public class ViewHolder extends RecyclerView.ViewHolder {

    public TextView username;
    public ImageView profile_image;
    public TextView title;
    public TextView description;
    public Button join;

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

        username = itemView.findViewById(R.id.username);
        profile_image = itemView.findViewById(R.id.profile_image);
        title = itemView.findViewById(R.id.title);
        description = itemView.findViewById(R.id.description);
        join = itemView.findViewById(R.id.btn_join);

    }
}

private void getUserInfo(final TextView username, final ImageView profile_image, final String sPublisher) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Users").child(sPublisher);
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            final User user = dataSnapshot.getValue(User.class);
            username.setText(user.getUsername());

            if (user.getImageURL().equals("default")) {
                profile_image.setImageResource(R.mipmap.ic_launcher);
            } else {
                Glide.with(mContext.getApplicationContext()).load(user.getImageURL()).into(profile_image);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}

это мой метод joinEvent в нем

private void joinEvent(String fuser, String sId, String publisher){
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Interested");

    String iId = reference.push().getKey();

    HashMap<String, Object> map = new HashMap<>();
    map.put("interested", fuser);
    map.put("sid", sId);
    map.put("iId", iId);
    map.put("publisher", publisher);
    map.put("accepted", "");
    reference.child(iId).setValue(map);

    //join.setBackgroundColor(0xFFFF0000);

}

и мои методы checkIfInterested и checkIfAccepted в нем

private void checkIfInterested(final Button join_btn, final String sid, final String fuser) { 

    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Interested");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                final Interested interested = snapshot.getValue(Interested.class);
                assert interested != null;
                if (interested.getSid().equals(sid) && interested.getInterested().equals(fuser)) {
                    join_btn.setBackgroundColor(0xFFFF0000);
                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

private void checkIfAccepted(final Button join_btn, final String sid, final String fuser) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Interested");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                final Interested interested = snapshot.getValue(Interested.class);
                assert interested != null;
                if (interested.getSid().equals(sid) && interested.getAccepted().equals(fuser)) {
                    join_btn.setBackgroundColor(0xff00ff00);
                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

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

Ответы [ 2 ]

1 голос
/ 23 октября 2019

RecyclerView используется ViewHolder дизайн патентов. Вот почему его вид повторно используется между различными предметами. Итак, ваш звонок на holder.join.getBackground() не даст вам точного результата для этого предмета. Чтобы избежать, вам следует хранить color внутри модели [здесь: Предложение] и принимать решения на основе этого.

Шаг - 1:

class Suggestion {

    ...

    private int buttonColor = 0xF0DC82;

    public int getButtonColor() {
        return buttonColor;
    }

    public void setButtonColor(int buttonColor) {
        this.buttonColor = buttonColor;
    }

    ...

}

Шаг - 2: обновите свои checkIfAccepted и checkIfAccepted, как показано ниже:

private void checkIfAccepted(Suggestion suggestion, final String fuser) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Interested");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                final Interested interested = snapshot.getValue(Interested.class);
                assert interested != null;
                if (interested.getSid().equals(suggestion.getSid()) && interested.getAccepted().equals(fuser)) {
                    suggestion.setButtonColor(0xff00ff00);
                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

private void checkIfAccepted(Suggestion suggestion, final String fuser) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Interested");
    reference.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                final Interested interested = snapshot.getValue(Interested.class);
                assert interested != null;
                if (interested.getSid().equals(suggestion.getSid()) && interested.getAccepted().equals(fuser)) {
                    suggestion.setButtonColor(0xff00ff00);
                }
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

Шаг - 3: Затем измените onBindViewHolder реализацию:

@Override
public void onBindViewHolder(@NonNull final SuggestionHomeAdapter.ViewHolder holder, final int position) {

    final Suggestion suggestion = mSuggestion.get(position);
    fuser = FirebaseAuth.getInstance().getCurrentUser();

    holder.title.setText(suggestion.getTitle());
    holder.description.setText(suggestion.getDescription());
    holder.join.setBackgroundColor(suggestion.getButtonColor());
    getUserInfo(holder.username, holder.profile_image, suggestion.getSpublisher());

    checkIfInterested(suggestion, fuser.getUid());
    checkIfAccepted(suggestion, fuser.getUid());

    holder.join.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(suggestion.getButtonColor() != 0xFFFF0000 && suggestion.getButtonColor() != 0xff00ff00){
                joinEvent(fuser.getUid(), suggestion);
                notifyItemChanged(position);
            }
        }
    });
}

Шаг - 4: Последнее обновление joinEvent

private void joinEvent(String fuser, Suggestion suggestion) {
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Interested");

    String iId = reference.push().getKey();

    HashMap<String, Object> map = new HashMap<>();
    map.put("interested", fuser);
    map.put("sid", suggestion.getSid());
    map.put("iId", iId);
    map.put("publisher", suggestion.getSpublisher());
    map.put("accepted", "");
    reference.child(iId).setValue(map);

    suggestion.setButtonColor(0xFFFF0000);
}
1 голос
/ 23 октября 2019

Прежде всего, вы не должны использовать параметр позиции onBindViewHolder () в вашем OnClickListener. Это ненадежно, и вы должны вместо этого использовать holder.getAdapterPosition ().

Далее, RecyclerViews повторно используют или «перерабатывают» представления, что делает их эффективными для того, чтобы иметь много представлений в списке. Однако у них есть проблема, если вы хотите, чтобы разные элементы имели разные цвета фона. Решение состоит в том, чтобы отслеживать, какие из них вы хотите «выбрать» или иметь другой фон, а затем обновлять его соответствующим образом. Итак:

if(item.isSelected())
    setBackgroundColor(<highlight_color>)
else
    setBackgroundColor(<default_color>)

Необходимо убедиться, что для невыбранных по-прежнему задан фон по умолчанию, так как представление переработчика могло случайно использовать подсвеченный вместо него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...