简体   繁体   中英

LiveData with added new item via push notification not update the list

I tried to add new message item who arrived from push notification to list.
I tried to achieve this by live data. I used databinding in recyclerview and in main activity.
The func onChanged is not called when item is added to live data list in MsgViewModel class.
what I doing wrong?

public class MyFirebaseMessagingService extends FirebaseMessagingService {

 ......

    private void showNotification(Map<String, String> data) {

         id = data.get("id");
         phone = data.get("phone");
         locations = data.get("locations");
         textMessage = data.get("textMessage");

         MsgViewModel viewModel = new MsgViewModel(getApplication());

        viewModel.addMessage(new Message(id, phone, locations, textMessage));
    }


public class MsgViewModel extends AndroidViewModel {

    private MutableLiveData<ArrayList<Message>> messageArrayList;

    public MsgViewModel(@NonNull Application application) {
        super(application);
        messageArrayList = new MutableLiveData<>();
    }

    public void addMessage(Message message){
        List<Message> messages = messageArrayList.getValue();
        ArrayList<Message> cloneMessageList;
        if(messages == null){
            cloneMessageList = new ArrayList<>();
        }else {
            cloneMessageList = new ArrayList<>(messages.size());
            for (int i = 0; i < messages.size(); i++){
                cloneMessageList.add(new Message(messages.get(i)));
            }
        }
        cloneMessageList.add(message);
        messageArrayList.postValue(cloneMessageList);
    }

    public MutableLiveData<ArrayList<Message>> getMessageList(){
        return messageArrayList;
    }
}

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;
    private MsgViewModel msgViewModel;
    private MsgListAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        binding.contentMainId.recyclerview.setHasFixedSize(true);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        binding.contentMainId.recyclerview.setLayoutManager(layoutManager);

        msgViewModel = new ViewModelProvider(this).get(MsgViewModel.class);

        msgViewModel.getMessageList().observe(this, new Observer<ArrayList<Message>>() {
            @Override
            public void onChanged(ArrayList<Message> list) {
                mAdapter = new MsgListAdapter(getApplication(), list);
                binding.contentMainId.recyclerview.setAdapter(mAdapter);
               // mAdapter.notifyDataSetChanged();
            }
        });

    }

Any help why it is not update the adapter will be appreciated
==========Update=======
onChanged() method not called when have new item who added to the list

The problem here is how you instantiate your viewModels. If I understand correctly, you want them to be the same instance in both the activity and the messaging service . One is MsgViewModel viewModel = new MsgViewModel(getApplication());

The other one is msgViewModel = new ViewModelProvider(this).get(MsgViewModel.class);

On the second one this stands for the current instance of the activity. And its context is different from the one you get from getApplication() .

As far as I know, when you call 'postValue()' or something 'setValue()' method, you should give new object of something like oldMutableList.toList().

In other words, after a list is entered as a parameter in 'postvalue()'method of livedata, even if a new value is added to the list, livedata is not recognized. In order for the observer to recognize, the newly created list object must be entered as a parameter when calling postvalue again.

_liveData.postValue(list.toList()) // "list.toList()" <- this code generate new List object which has another hashcode.
or
_liveData.postValue(list.sortedBy(it.somethingField))

sorry about this kotlin code, not java.

// this original in your code
messageArrayList.postValue(cloneMessageList);
// change to these codes
messageArrayList.postValue(new ArrayList(cloneMessageList));
or
messageArrayList.postValue(cloneMessageList.toList());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM