Recyclerview не обновляется после перезапуска активности - PullRequest
1 голос
/ 18 июня 2020

Итак, я не уверен в названии этого вопроса, но вот оно. У меня есть рециклер для моей чат-комнаты. В первый раз, когда действие началось, у него нет проблем с отображением сообщений, но после нажатия кнопки возврата к основному действию, показывающему все комнаты чата, затем снова щелкните ту же комнату чата, она ничего не отображает. Затем, после отправки сообщения, он может снова отобразить все сообщения. Не знаю, что случилось, помогите, пожалуйста. О, я уже пробовал несколько вещей и просматривал inte rnet, но, поскольку я не уверен, что это за ключевое слово, я застрял сейчас

Хорошо, вот что

Первое основное действие (игнорируйте две другие вкладки, оно пусто)

Основное действие

Затем откройте чат-комнату

Штраф при первом открытии чата

Затем нажмите кнопку «Назад», вернитесь к MainActivity, затем откройте ту же комнату, и чат не отображается

в чате ничего не отображается

Затем он снова отображает сообщения после отправки нового сообщения

новое сообщение

Я попытался разместить notifyDataSetChanged () для различных событий, таких как onStart, onCreate et c, но ничего не работает;

вот моя активность в чате

package com.divistant.chat.ui.chat;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.divistant.chat.R;
import com.divistant.signup.UserModel;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ChatActivity extends AppCompatActivity {
    LinearLayout layout;
    ImageView send;
    EditText message;
    ScrollView scrollView;
    DatabaseReference refrence1;
    DatabaseReference refrence2;
    RecyclerView rv;
    List<ChatModel> chats = new ArrayList<>();
    ChatActivityAdapter adapter;

    FirebaseUser cUser;
    UserModel target;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);
        Log.w("EVENT","ON Create");

        Intent intent = getIntent();
        target = (new Gson()).fromJson(intent.getStringExtra("target"),UserModel.class);

        send = (ImageView)findViewById(R.id.sendButton);
        message = (EditText)findViewById(R.id.messageArea);
        scrollView = (ScrollView)findViewById(R.id.scrollView);
        rv = (RecyclerView) findViewById(R.id.main_chat_rv);
        cUser = FirebaseAuth.getInstance().getCurrentUser();
        adapter = new ChatActivityAdapter(chats);

        final LinearLayoutManager manager = new LinearLayoutManager(ChatActivity.this,
                LinearLayoutManager.VERTICAL, false);
        rv.setLayoutManager(manager);


        refrence1 = FirebaseDatabase.getInstance()
                .getReference()
                .child("messages")
                .child(cUser.getUid() + "_" + target.getUserId());

        refrence2 = FirebaseDatabase.getInstance()
                .getReference()
                .child("messages")
                .child(target.getUserId() + "_" + cUser.getUid());

        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Log.w("SEND","send message");

                if(message.getText().toString().length() > 0){
                    ChatModel chat = new ChatModel();
                    chat.setSender(cUser.getEmail());
                    chat.setMessage(message.getText().toString());
                    chat.setReceiver(target.getEmailAddress());
                    chat.setSenderUid(cUser.getUid());
                    chat.setReceiverUid(target.getUserId());
                    chat.setTimestamp((new Date()).getTime());
                    DatabaseReference ref1 = refrence1.push();
                    ref1.setValue(chat);
                    DatabaseReference ref2 = refrence2.push();
                    ref2.setValue(chat);

                    message.setText("");
                }
            }
        });



        refrence1.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                chats.clear();

                for(DataSnapshot snapshot :dataSnapshot.getChildren()){
                    ChatModel chat = new ChatModel();
                    chat.setSender(snapshot.child("sender").getValue(String.class));
                    chat.setMessage(snapshot.child("message").getValue(String.class));
                    chat.setReceiver(snapshot.child("receiver").getValue(String.class));
                    chat.setSenderUid(snapshot.child("senderUid").getValue(String.class));
                    chat.setReceiverUid(snapshot.child("receiverUid").getValue(String.class));
                    chat.setTimestamp(1592455659978L);

                    chats.add(chat);
                }
                adapter.setmChats(chats);
                adapter.notifyDataSetChanged();
                rv.scrollToPosition(adapter.getItemCount()-1);
                Log.e("[CH]","DATACHANGE " + chats.size());
            }



            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("[CH]","CANCEL");
            }
        });

        refrence1.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                chats.clear();
                adapter.notifyDataSetChanged();
                rv.scrollToPosition(adapter.getItemCount()-1);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                Log.e("[CH]","DB CHANGE");
            }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
                Log.e("[CH]","DB REMOVE");
            }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                Log.e("[CH]","Child Moved");
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.e("[CH]","DB ERROR");
            }
        });


        rv.setAdapter(adapter);

    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e("[CH]","" + adapter.getItemCount());
    }
}

Затем вот мой ChatActivityAdapter

package com.divistant.chat.ui.chat;

import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.divistant.chat.R;
import com.google.firebase.auth.FirebaseAuth;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ChatActivityAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
    private static final int VIEW_TYPE_ME = 1;
    private static final int VIEW_TYPE_OTHER = 2;
    List<ChatModel> mChats;


    public void setmChats(List<ChatModel> mChats) {
        this.mChats = mChats;
    }

    public ChatActivityAdapter(List<ChatModel> mChats) {
        this.mChats = mChats;
        Log.e("ADAPTER","CONSTRUCTED " + mChats.size());
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        RecyclerView.ViewHolder viewHolder = null;
        switch (viewType) {
            case VIEW_TYPE_ME:
                View viewChatMine = layoutInflater.inflate(R.layout.chat_item, parent, false);
                viewHolder = new MyChatViewHolder(viewChatMine);
                break;
            case VIEW_TYPE_OTHER:
                View viewChatOther = layoutInflater.inflate(R.layout.chat_item_other, parent, false);
                viewHolder = new OtherChatViewHolder(viewChatOther);
                break;
        }
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (TextUtils.equals(mChats.get(position).senderUid,
                FirebaseAuth.getInstance().getCurrentUser().getUid())) {
            configureMyChatViewHolder((MyChatViewHolder) holder, position);
        } else {
            configureOtherChatViewHolder((OtherChatViewHolder) holder, position);
        }
    }
    private void configureMyChatViewHolder(final MyChatViewHolder myChatViewHolder, int position) {
        ChatModel chat = mChats.get(position);
        SimpleDateFormat sfd = new SimpleDateFormat("hh:mm a");
        String date=sfd.format(new Date(chat.timestamp).getTime());
        myChatViewHolder.senderMsgTime.setText(date);
        myChatViewHolder.txtChatMessage.setText(chat.getMessage());
    }

    private void configureOtherChatViewHolder(final OtherChatViewHolder otherChatViewHolder, int position) {
        final ChatModel chat = mChats.get(position);
        SimpleDateFormat sfd = new SimpleDateFormat("hh:mm a");
        String date=sfd.format(new Date(chat.timestamp).getTime());
        otherChatViewHolder.receiverMsgTime.setText(date);
        otherChatViewHolder.txtChatMessage.setText(chat.getMessage());
    }

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

    @Override
    public int getItemViewType(int position) {
        if (TextUtils.equals(mChats.get(position).senderUid,
                FirebaseAuth.getInstance().getCurrentUser().getUid())) {
            return VIEW_TYPE_ME;
        } else {
            return VIEW_TYPE_OTHER;
        }
    }

    private static class MyChatViewHolder extends RecyclerView.ViewHolder {
        private TextView txtChatMessage, txtUserAlphabet;
        private TextView senderMsgTime;

        public MyChatViewHolder(View itemView) {
            super(itemView);
            txtChatMessage = (TextView) itemView.findViewById(R.id.text_view_chat_message);
            txtUserAlphabet = (TextView) itemView.findViewById(R.id.text_view_user_alphabet);
            senderMsgTime=(TextView) itemView.findViewById(R.id.senderMsgTime);
        }
    }

    private static class OtherChatViewHolder extends RecyclerView.ViewHolder {
        private TextView txtChatMessage, txtUserAlphabet;
        private TextView receiverMsgTime;

        public OtherChatViewHolder(View itemView) {
            super(itemView);
            txtChatMessage = (TextView) itemView.findViewById(R.id.text_view_chat_message_ot);
            txtUserAlphabet = (TextView) itemView.findViewById(R.id.text_view_user_alphabet_ot);
            receiverMsgTime=(TextView) itemView.findViewById(R.id.receiverMsgTime_ot);
        }
    }




}

Спасибо

Ответы [ 4 ]

1 голос
/ 18 июня 2020

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

 @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            chats.clear();
            adapter.notifyDataSetChanged();
            rv.scrollToPosition(adapter.getItemCount()-1);
        }

Теперь измените код, добавив строки

 @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            chats.clear();
            for(DataSnapshot snapshot :dataSnapshot.getChildren()){
                ChatModel chat = new ChatModel();
                chat.setSender(snapshot.child("sender").getValue(String.class));
                chat.setMessage(snapshot.child("message").getValue(String.class));
                chat.setReceiver(snapshot.child("receiver").getValue(String.class));
                chat.setSenderUid(snapshot.child("senderUid").getValue(String.class));
            chat.setReceiverUid(snapshot.child("receiverUid").getValue(String.class));
                chat.setTimestamp(1592455659978L);

                chats.add(chat);
            }
            adapter.setmChats(chats);
            adapter.notifyDataSetChanged();
            rv.scrollToPosition(adapter.getItemCount()-1);
        }
0 голосов
/ 18 июня 2020

Можете поставить rv.setAdapter (адаптер) после rv.setLayoutManager (manager) ;? И вы проверяете, всегда ли вызывается метод onDataChange (...) ??

0 голосов
/ 18 июня 2020

Вы можете использовать следующий код в адаптере, где вы хотите обновить sh recyclerview, например, в функции @Override public void onBackPressed(){}. Если ваш массив чатов изменился, вам следует обновить sh этот адаптер.

mAdapter = new ChatActivityAdapter(context, chats.get(chats.size() - 1), chats);
recyclerView.setAdapter(mAdapter);
0 голосов
/ 18 июня 2020

в моем случае я использовал onResume()

  @Override
    protected void onResume() {
        super.onResume();
         adapter.notifyDataSetChanged();
    }
...