java - 回收站适配器 onClick 项目出现问题

标签 java android firebase firebase-realtime-database android-recyclerview

我的回收器适配器中的 onClick 方法有问题。

我从 fragment 提供我的适配器,然后在适配器中我从 firebase 获得我需要的所有信息,包括用户信息和已经点击的按钮“加入”(我为该按钮设置了红色背景)。一切正常,直到我单击之前未按下的按钮“加入”。按钮的颜色发生变化(工作正常并使用 joinEvent 方法将信息保存到 firebase)但有时附近按钮的颜色也会发生变化。我对这个问题进行了研究,但对我没有任何帮助。我尝试将位置分配给方法(joinEvent、checkIfInterested、checkIfAccepted)而不是 holders,但这不起作用。我将不胜感激任何帮助!这是我的适配器:

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) {

        }
    });
}

Firebase 一切正常,但按钮会在不应该改变颜色时改变颜色。

最佳答案

首先,您不应在 OnClickListener 中使用 onBindViewHolder() 的位置参数。这是不可靠的,您应该改用 holder.getAdapterPosition()。

接下来,RecyclerViews 重用或“回收” View ,这使得它们在列表中有许多 View 时非常有效。但是,如果您希望不同的项目具有不同的背景颜色,它们就会出现问题。解决方案是跟踪您想要“选择”或具有不同背景的那些,然后相应地更新它。 所以:

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

您需要确保未选中的那些仍设置为默认背景,因为回收器 View 可能不小心在其位置使用了突出显示的背景。

关于java - 回收站适配器 onClick 项目出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58527683/

相关文章:

java - 输入空输入时如何跳出循环

java - 如何将jtable中的值插入到mysql中?

java - FXML 按钮导致空指针,硬编码按钮则不会

java - 套接字 - 地址已在使用中

安卓获取当前位置

java - CountDownTimer cancel() 不会取消计时器并继续工作

ios - tableView 显示重复值

ios - Firebase 查询错误处理

java - 如何在JSP中格式化时间

Android AsyncTask 在 doInBackground 返回多个值用于 onPostExecute