FirebaseRecyclerAdapter, дублирующий объекты в представлении корзины - PullRequest
0 голосов
/ 18 декабря 2018

Моя структура: My Structure

Я занимаюсь разработкой приложения для чата с использованием базы данных 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();
    }
}
}

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

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

Спасибо

1 Ответ

0 голосов
/ 18 декабря 2018

Проблема в том, что каждый раз, когда вы прокручиваете, чтобы снова сделать видимым новый элемент, он запускает код внутри вашего 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;
}
...