【问题标题】:FirebaseRecyclerAdapter duplicating the objects in recycle viewFirebaseRecyclerAdapter 在回收视图中复制对象
【发布时间】:2018-12-18 06:00:49
【问题描述】:

我的结构:

我正在使用 firebase 实时数据库开发一个聊天应用程序。我正在使用 FirebaseRecyclerAdapter 来显示消息。但事情是在滚动,消息被重复和乱序。

这是我的实现:

public class FirebaseChatActivity extends AppCompatActivity {


private String messageSenderId;
private String messageReceiverId;

private FirebaseRecyclerAdapter<ChatMessage, MessageViewHolder> firebaseRecyclerAdapter;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_firebase_chat);

    RecyclerView recyclerView = findViewById(R.id.rv_firebase_chat_activity);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));


    messageSenderId = "eoSU5m7PyucyC9h30JfHhV6S8Av2";
    messageReceiverId = "ZOqofCid0XN5ovIAj1mXhRYxdnO2";

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    Query query = rootRef.child("messages").child(messageSenderId).child(messageReceiverId);


    FirebaseRecyclerOptions<ChatMessage> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<ChatMessage>()
            .setQuery(query, ChatMessage.class)
            .build();


    firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<ChatMessage, MessageViewHolder>(firebaseRecyclerOptions) {
        @Override
        protected void onBindViewHolder(@NonNull MessageViewHolder messageViewHolder, int position, @NonNull ChatMessage message) {


            if (message.getMessageType().equals("text")) {
                messageViewHolder.showMessage.setText(message.getMessageText());
            } else if (message.getMessageType().equals("image")) {

                try {
                    Glide.with(getApplicationContext())
                            .load(message.getPhotoUrl())
                            .placeholder(R.drawable.no_image2)
                            .error(R.drawable.image_1)
                            .into(messageViewHolder.photoImageView);
                } catch (Exception e) {
                    Log.d("MessageAdapterLog", e.toString());
                }

            }

        }

        @Override
        public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {


            android.view.View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item_right, parent, false);
            return new MessageViewHolder(view);


        }
    };
    recyclerView.setAdapter(firebaseRecyclerAdapter);
}


private class MessageViewHolder extends RecyclerView.ViewHolder {


    public TextView showMessage;
    public ImageView photoImageView;

    public MessageViewHolder(@NonNull android.view.View itemView) {
        super(itemView);

        showMessage = itemView.findViewById(R.id.show_message);
        photoImageView = itemView.findViewById(R.id.photo_image_view);
    }

}


@Override
protected void onStart() {
    super.onStart();
    firebaseRecyclerAdapter.startListening();
}

@Override
protected void onStop() {
    super.onStop();

    if (firebaseRecyclerAdapter!= null) {
        firebaseRecyclerAdapter.stopListening();
    }
}
}

我尝试了许多不同的解决方案,例如设置为提到的here 以及 .addChildEventListener(完全不同的实现)但无法解决问题。

附上完整的活动代码以及数据库结构。请让我知道我做错了什么。

谢谢

【问题讨论】:

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


    【解决方案1】:

    问题在于,每次滚动时,为了使新项目再次可见,它会运行 onBindViewHolder 中的代码来膨胀该视图并重新绑定它。

    if (message.getMessageType().equals("text")) {
                    messageViewHolder.showMessage.setText(message.getMessageText());
                } else if (message.getMessageType().equals("image")) {
    
                    try {
                        Glide.with(getApplicationContext())
                                .load(message.getPhotoUrl())
                                .placeholder(R.drawable.no_image2)
                                .error(R.drawable.image_1)
                                .into(messageViewHolder.photoImageView);
                    } catch (Exception e) {
                        Log.d("MessageAdapterLog", e.toString());
                    }
    
                }
    
            }
    

    要解决这个问题,您需要覆盖适配器中的两个方法

    @Override
    public long getItemId(int position) {
        return position;
    }
    
    @Override
    public int getItemViewType(int position) {
       return position;
    }
    

    【讨论】:

    • 哇。 @Gaston Man,您是救生员。你无法想象我有多开心。上帝祝福你。 :)
    • 任何时候约翰,只要问你是否还有其他问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 2015-06-12
    • 1970-01-01
    • 2016-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多