RecyclerViewアダプタのnotifyDataSetChangedがRecyclerViewを更新しない

androidXP

私が持っているRecyclerViewfirebaseリアルタイムデータベースとローカルのSQLiteデータベースとのチャットアプリのために。メッセージをローカルデータベース(SQLite)に保存してから、を呼び出していadapter.notifyDataSetChanged()ます。

メッセージがすでにデータベースにある場合(メッセージの一意のID)、SQLiteはデータベースinsertOrThrowメソッドで0を返しますこのように空き状況を確認しています。

if (id == 0) {
    Log.d(TAG,"Database Already Has Value Of This Random Id ");
    adapter.notifyDataSetChanged();
} else {
    Chat_Wrapper chat_wrapper = new Chat_Wrapper(Chat_Msg, null, null, null, null, null, null, Chat_TimeStamp, UserPhone_Intent, UserImage_Intent, Chat_FROM, null,null,id);
    message.add(chat_wrapper);
    adapter.notifyDataSetChanged();
}

ただし、elseステートメントが呼び出されても、RecyclerView画面は更新されませんが、バックグラウンドでメッセージを入力または受信すると、ローカルデータベースに保存されますが、画面には表示されません。

チャットRecyclerViewは次の場合に機能します

  1. 最近のアプリからアプリをクリアすると
  2. ローカルデータベースからのデータのフェッチを停止します
  3. チャット画面の最初の起動

通知から直接チャット画面にアクセスすると、この問題が発生します。

これが私がチャットフラグメントを通常ロードする方法です。

getFragmentManager().beginTransaction().add(R.id.Navigation_Drawer, chatFragment).commit();

読み込んでFragmentからNotification使用してAsynctask

((Navigation_Drawer)context).getFragmentManager().beginTransaction().replace(R.id.Navigation_Drawer, chatFragment).commit();

これが、通知からChatFragmentを起動する方法です。

public class FireBase_Messaging_Service extends FirebaseMessagingService {

    public static final String TAG="###FireBase MSG###";
    public static final int NOTIFICATION=5;
    String UserName;
    String ID;
    String Msg;

    Map<String,String> data;
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        Log.d(TAG,"From "+remoteMessage.getFrom());
        if (remoteMessage.getData().size()>0){
            data = remoteMessage.getData();
            Log.d(TAG,"Message Data "+remoteMessage.getData());
            data = remoteMessage.getData();

            UserName = data.get("name");
            ID = data.get("ID");
            Msg = data.get("Message");

            showNotification(Msg,ID,UserName);
        }

        if (remoteMessage.getNotification()!=null){
            Log.d(TAG,"Message Notification Body "+remoteMessage.getNotification().getBody());
           // Toast.makeText(this, "Notification "+remoteMessage.getNotification().getBody(), Toast.LENGTH_LONG).show();
        }
    }

    private void showNotification(String Message,String ID,String UserName) {
        Log.d(TAG,"Show Notification "+Message+" "+ID);
        Intent intent=new Intent(this, Navigation_Drawer.class);
        intent.putExtra("Type","Text");
        //intent.putExtra("Type",MsgType);
        intent.putExtra("ID",ID);
        intent.putExtra("uname",UserName);
        intent.putExtra("Message",Msg);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent=PendingIntent.getActivity(this,NOTIFICATION,intent,PendingIntent.FLAG_UPDATE_CURRENT);
        int color = getResources().getColor(R.color.black);
        String ChannelID = "Message";
        notificationChannel(ChannelID,"Chat");
        NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(),ChannelID)
                .setSmallIcon(R.drawable.default_x)
                .setColor(color)
                .setContentTitle(UserName)
                .setContentText(Message)
                .setChannelId(ChannelID)
                .setTicker("My App")
                .setDefaults(Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND | Notification.FLAG_SHOW_LIGHTS)
                .setLights(0xff00ff00, 1000, 500) // To change Light Colors
                .setStyle(new NotificationCompat.BigTextStyle().bigText(Message))//For Expandable View
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(pendingIntent)
                .setAutoCancel(true);

        NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
        managerCompat.notify(NOTIFICATION,builder.build());
    }

    @Override
    public void onDeletedMessages() {
        super.onDeletedMessages();
    }

    private void notificationChannel (String ChannelID, String channelName) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel  channel = new NotificationChannel(ChannelID,channelName, NotificationManager.IMPORTANCE_DEFAULT);
            channel.setLightColor(Color.GREEN);
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
    }
}

また、リストmessage.add(chat_wrapper)データを追加した後、最初にサイズの増加が表示されますが、whileループが終了すると、の最後のサイズが表示されることにも気づきましArrayList

これがChatFragmentクラスです。

 public class Chat_Screen_Fragment extends Fragment implements View.OnClickListener, ChildEventListener{

    public static final String TAG = "###CHAT SCREEN###";
    List<Chat_Wrapper> message = new ArrayList<>();

    Chat_Adapter adapter;
    RecyclerView recyclerView;
    LinearLayoutManager layoutManager;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v=inflater.inflate(R.layout.chat_screen_main_fragment,container,false);
        setRetainInstance(true);
        // GET INTENT VALUES FROM USER PROFILE CLASS

        UserName_Intent = getArguments().getString("Get_Name");
        UserImage_Intent = getArguments().getString("Get_Image");
        UserPhone_Intent = getArguments().getString("Get_Phone");
        UserID_Intent = getArguments().getString("Get_ID");
        FirebaseToken_Intent = getArguments().getString("Get_Token"); //Firebase Token of other person
        Room_Name_Intent = getArguments().getString("Get_Other"); // Room Name of chat
        UserLastSeen_Intent=getArguments().getString("LastSeen");
        //Sender_FCMToken = Session.getFirebaseID();
        // RECYCLER VIEW
        recyclerView = v.findViewById(R.id.Chat_Screen_Message_List);
        layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setStackFromEnd(true);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(layoutManager);
        databaseReference = FirebaseDatabase.getInstance().getReference().child(Room_Name_Intent);
        databaseReference.addChildEventListener(this);

        adapter = new Chat_Adapter(getActivity(), message);
        recyclerView.setAdapter(adapter);
        // FETCH OLD MESSAGE FROM DATABASE
        chatDatabase();
        return v;
    }
    // FIREBASE REAL TIME DATABASE WHICH FETCH ALL MESSAGES (SYNC) FROM ONLINE DATABASE
    @Override
    public void onChildAdded(DataSnapshot dataSnapshot, String s) {
        append_chat_conversation(dataSnapshot);
    }

    @Override
    public void onChildChanged(DataSnapshot dataSnapshot, String s) {
        append_chat_conversation(dataSnapshot);
    }

    @Override
    public void onChildRemoved(DataSnapshot dataSnapshot) {

    }

    @Override
    public void onChildMoved(DataSnapshot dataSnapshot, String s) {

    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }

    private synchronized void append_chat_conversation(DataSnapshot dataSnapshot) {
        iterator = dataSnapshot.getChildren().iterator();

        while (iterator.hasNext()) {

            // GETTING DATA FROM FIREBASE DATABASE 

            Chat_Msg = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FROM = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FROM_ID = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_TO = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_TimeStamp = (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_Type= (String) ((DataSnapshot) iterator.next()).getValue();
            Random_ID=(String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FCM_FROM= (String) ((DataSnapshot) iterator.next()).getValue();
            Chat_FCM_TO= (String) ((DataSnapshot) iterator.next()).getValue();

            Log.d(TAG, "Chat Items " + Chat_Msg + " " + Random_ID);

            Chat_Database tempChatDatabase = new Chat_Database(getActivity());
            boolean hasValue = tempChatDatabase.CheckValueExist(Random_ID);
            Log.d(TAG,"DATABASE ALREADY HAS VALUE OF TIMESTAMP= "+hasValue);

            if (!hasValue) {
                Log.d(TAG,"DATABASE DON'T HAVE SAME ENTRY FOR TIME STAMP. ENTERED INTO HAS VALUE");
                Log.d(TAG,"Chat Message "+Chat_Msg);

           if (Chat_Type.equals("Typed_Message")) {
                Log.d(TAG, "VIEW TYPE IS Message " + Chat_Msg);
                long id = chat_database.Insert_Chat(Session.getUserID(),Room_Name_Intent, UserID_Intent, "Text", Chat_Msg, Chat_FROM, Chat_TO, Chat_TimeStamp, Chat_FCM_FROM, Chat_FCM_TO, Session.getPhoneNO(), UserPhone_Intent,Random_ID,UserImage_Intent,UserLastSeen_Intent,Chat_FROM_ID);

                //Adding Chat Data Into Database
                Log.d(TAG,"Database Entry ID "+id);

                if (id == 0) {
                    Log.d(TAG,"Database Already Has Value Of This Random Id ");
                    adapter.notifyDataSetChanged();
                    continue;

                } else {
                    Log.d(TAG,"Database Don't Has Value Of This Random Id ");
                    Log.d(TAG,"Message Size "+message.size());
                    Chat_Wrapper chat_wrapper = new Chat_Wrapper(Chat_Msg, null, null, null, null, null, null, Chat_TimeStamp, UserPhone_Intent, UserImage_Intent, Chat_FROM, null,null,id);
                    message.add(chat_wrapper);
                    Log.d(TAG,"Message Size "+message.size());
                    adapter.notifyDataSetChanged();
                    Log.d(TAG,"Adapter Notified Data Set "+adapter.getItemCount());
                    recyclerView.post(new Runnable() {
                        @Override
                        public void run() {
                            Log.d(TAG, "Moving to Bottom");
                            recyclerView.smoothScrollToPosition(adapter.getItemCount());
                        }
                    });
                }
        }

        Log.d(TAG, "MESSAGE ARRAY SIZE " + message.size());
        chat_database.isDatabaseClose();
}

    private void chatDatabase(){
        //Database Init and Filling Adapter
        Log.d(TAG,"Chat Database Function");
        chat_database=new Chat_Database(getActivity());
        chatCursor=chat_database.getUserChat(UserID_Intent);
        boolean checkDB_Exist=functions.DatabaseExist(getActivity(),"CHAT_DATABASE.DB");
        boolean chatItemsCounts=chatCursor.getCount()>0;
        chatCursor.moveToFirst();
        Log.d(TAG,"Value At Chat Database "+ checkDB_Exist+" "+chatItemsCounts);
        if (checkDB_Exist && chatCursor.getCount()>0 && chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_USER_ID")).equals(UserID_Intent)){

            Log.d(TAG,"Database Exist Chat Database");
            message.clear();
            chatCursor.moveToFirst();
            do {
                database_rowID=chatCursor.getInt(chatCursor.getColumnIndex("ID"));
                database_userID=chatCursor.getString(chatCursor.getColumnIndex("USER_ID"));
                database_RoomName =chatCursor.getString(chatCursor.getColumnIndex("ROOM_NAME"));
                database_ReceiverID=chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_USER_ID"));
                database_MessageType=chatCursor.getString(chatCursor.getColumnIndex("MESSAGE_TYPE"));
                database_Message=chatCursor.getString(chatCursor.getColumnIndex("USER_MESSAGE"));
                database_MsgFrom=chatCursor.getString(chatCursor.getColumnIndex("SENDER_NAME"));
                database_MsgTo=chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_NAME"));
                database_TimeStamp=chatCursor.getString(chatCursor.getColumnIndex("TIME_STAMP"));
                database_FCMfrom=chatCursor.getString(chatCursor.getColumnIndex("SENDER_TOKEN"));
                database_FCMto=chatCursor.getString(chatCursor.getColumnIndex("RECEIVER_TOKEN"));
                database_LocalPath=chatCursor.getString(chatCursor.getColumnIndex("DOWNLOADED_AT"));
                database_PhoneFrom=chatCursor.getString(chatCursor.getColumnIndex("MY_PHONE"));
                database_PhoneTo=chatCursor.getString(chatCursor.getColumnIndex("OTHER_PHONE"));

                Log.d(TAG,"Value Of Database Message String = "+database_Message);
                Log.d(TAG,"Row ID of Database "+database_rowID);
                // Check Message Type


                    Log.d(TAG,"Message Type Is Text");
                    Chat_Wrapper text = new Chat_Wrapper(database_Message, null, null, null, null, null, null, database_TimeStamp, database_PhoneTo, UserImage_Intent, database_MsgFrom,null,null,database_rowID);
                    message.add(text);



            }
            while(chatCursor.moveToNext());

            Room_Name_Intent = database_RoomName;
            layoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(layoutManager);
            adapter.notifyDataSetChanged();
            chatCursor.close();
            boolean value = chat_database.isDatabaseClose();
            recyclerView.post(new Runnable() {
                @Override
                public void run() {
                    Log.d(TAG, "Moving to Bottom");
                    recyclerView.smoothScrollToPosition(message.size()-1);

                }
            });
            Log.d(TAG,"Value Of Database Close or Not "+value);

        }
    }
}
androidXP

私はAndroidのライフサイクルを少し掘り下げてこの問題を解決しました。上で述べたように、通知からChatFragmentに入ったときにのみ、この問題に直面します。私は活動状態の問題だけでした。コードは機能していました。私が行っていたことは、通知タップ(Firebaseコード内)で常にアクティビティを再作成します。

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);

たくさんのコードを掘り起こし、で複数のフラグを変更した後Intentandroid:launchMode="singleTask"私の問題を解決するだけです。アクティビティが存在しない場合にのみアクティビティを作成します。onDestroy通知をタップするときにアクティビティメソッドを呼び出さないようになりましたonStart再作成するアクティビティを回避するアクティビティを開始します。

このフラグをAndroidManifestのNavigationDrawerアクティビティタグに追加します。

 <activity
            android:name=".Navigation_Drawer"
            android:launchMode="singleTask"
            android:theme="@style/AppTheme"/>

この種の問題は開発者にとって本当に頭痛の種ですが、この1行のコードでこの問題を解決できるかどうかはわかりません。みんな助けてくれてありがとう。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

notifyDataSetChanged()がカスタムRecyclerViewアダプターで機能しない

分類Dev

アダプターがrecyclerviewを更新しない理由がわかりません

分類Dev

RecyclerviewアダプターでnotifyDataSetChanged()を設定します

分類Dev

アダプターがnotifyDataSetChangedを呼び出すたびに、recyclerviewが表示されない、消える、または消えるのはなぜですか?

分類Dev

notifyDataSetChanged()がアダプターを更新していません

分類Dev

ProgressBarがRecyclerViewアダプタで更新されない

分類Dev

ProgressBarがRecyclerViewアダプタで更新されない

分類Dev

Recyclerviewアダプターが更新されない

分類Dev

RecyclerViewアダプターが機能しないのはなぜですか?

分類Dev

RecyclerViewアダプタが機能しない

分類Dev

RecyclerViewアダプターがImageViewで現在のドローアブルを認識しない

分類Dev

アダプターを設定してもRecyclerViewが表示されない

分類Dev

RecyclerViewのアダプターを挿入する方法がわからない

分類Dev

アダプターメソッドnotifyDataSetChangedがリストビューを更新しない

分類Dev

ListAdapterがRecyclerViewのアイテムを更新しない

分類Dev

recyclerview notifyDataSetChanged()が機能しない

分類Dev

アダプタデータを更新した後、RecyclerViewに何も表示されない

分類Dev

notifyDataSetChangedが機能しないカスタムアダプタ

分類Dev

カスタムアダプタnotifyDataSetChangedが機能しない

分類Dev

異なるアクティビティからのResumeでrecyclerviewアダプタを更新します

分類Dev

Recyclerview notifyDataSetChanged(); 動作しない

分類Dev

E / RecyclerView:アダプターは接続されていません。レイアウトをスキップしてrecyclerviewにデータが表示されない

分類Dev

RecyclerViewアダプターが正しいレイアウトを膨らませない

分類Dev

画面回転アダプターnotifyDataSetChangedが機能しない

分類Dev

RecyclerViewアダプターがバターナイフで機能しない

分類Dev

Recyclerviewアダプター内で分割機能が正しく機能しない

分類Dev

FirebasevalueEventListenerとRecyclerViewアダプターのnotifyItemChangedが同じアクティビティで機能しない

分類Dev

フラグメント内のRecyclerViewでカスタムアダプタが機能しない

分類Dev

正しいデータを取得したにもかかわらず、RecyclerViewアダプターが正しく更新されないのはなぜですか(初回のみ)?

Related 関連記事

  1. 1

    notifyDataSetChanged()がカスタムRecyclerViewアダプターで機能しない

  2. 2

    アダプターがrecyclerviewを更新しない理由がわかりません

  3. 3

    RecyclerviewアダプターでnotifyDataSetChanged()を設定します

  4. 4

    アダプターがnotifyDataSetChangedを呼び出すたびに、recyclerviewが表示されない、消える、または消えるのはなぜですか?

  5. 5

    notifyDataSetChanged()がアダプターを更新していません

  6. 6

    ProgressBarがRecyclerViewアダプタで更新されない

  7. 7

    ProgressBarがRecyclerViewアダプタで更新されない

  8. 8

    Recyclerviewアダプターが更新されない

  9. 9

    RecyclerViewアダプターが機能しないのはなぜですか?

  10. 10

    RecyclerViewアダプタが機能しない

  11. 11

    RecyclerViewアダプターがImageViewで現在のドローアブルを認識しない

  12. 12

    アダプターを設定してもRecyclerViewが表示されない

  13. 13

    RecyclerViewのアダプターを挿入する方法がわからない

  14. 14

    アダプターメソッドnotifyDataSetChangedがリストビューを更新しない

  15. 15

    ListAdapterがRecyclerViewのアイテムを更新しない

  16. 16

    recyclerview notifyDataSetChanged()が機能しない

  17. 17

    アダプタデータを更新した後、RecyclerViewに何も表示されない

  18. 18

    notifyDataSetChangedが機能しないカスタムアダプタ

  19. 19

    カスタムアダプタnotifyDataSetChangedが機能しない

  20. 20

    異なるアクティビティからのResumeでrecyclerviewアダプタを更新します

  21. 21

    Recyclerview notifyDataSetChanged(); 動作しない

  22. 22

    E / RecyclerView:アダプターは接続されていません。レイアウトをスキップしてrecyclerviewにデータが表示されない

  23. 23

    RecyclerViewアダプターが正しいレイアウトを膨らませない

  24. 24

    画面回転アダプターnotifyDataSetChangedが機能しない

  25. 25

    RecyclerViewアダプターがバターナイフで機能しない

  26. 26

    Recyclerviewアダプター内で分割機能が正しく機能しない

  27. 27

    FirebasevalueEventListenerとRecyclerViewアダプターのnotifyItemChangedが同じアクティビティで機能しない

  28. 28

    フラグメント内のRecyclerViewでカスタムアダプタが機能しない

  29. 29

    正しいデータを取得したにもかかわらず、RecyclerViewアダプターが正しく更新されないのはなぜですか(初回のみ)?

ホットタグ

アーカイブ