Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewModel onchange gets called multiple times when back from Fragment

I am working with Android architecture components. What i want is when user type "0" in Edittext and click on Button to replace Fragment with new one , and if type anything else post Toast error message. In Problem is when i back from new Fragment(BlankFragment) and click on button again and type "0" again and click, onchange() is called multiple times so Fragment is get created multiple times

FragmentExample.class:

     @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container,                              Bundle savedInstanceState) {         manager = getActivity().getSupportFragmentManager();         viewmModel = ViewModelProviders.of(getActivity(), viewModelFactory)                 .get(VModel.class);          View v = inflater.inflate(R.layout.fragment_list, container, false);            b = (Button) v.findViewById(R.id.b);         et = (EditText) v.findViewById(R.id.et);          viewmModel.observeData().observe(getActivity(), new Observer<String>() {             @Override             public void onChanged(@Nullable String s) {                  if(s.equals("0")) {                     BlankFragment fragment = (BlankFragment) manager.findFragmentByTag(DETAIL_FRAG);                     if (fragment == null) {                         fragment = BlankFragment.newInstance();                     }                     addFragmentToActivity(manager,                             fragment,                             R.id.root_activity_detail,                             DETAIL_FRAG                     );                 } else {                     Toast.makeText(getContext(), "Wrong text", Toast.LENGTH_SHORT).show();                 }             }         });          b.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 viewmModel.setData(et.getText().toString());             }         });         return v;     }     private void addFragmentToActivity(FragmentManager fragmentManager, BlankFragment fragment, int root_activity_detail, String detailFrag) {         android.support.v4.app.FragmentTransaction transaction = fragmentManager.beginTransaction();         transaction.replace(root_activity_detail, fragment, detailFrag).addToBackStack(detailFrag);         transaction.commit();     } 

Repository class:

     public class Repository {     MutableLiveData<String> dataLive = new MutableLiveData<>();        public Repository() {      }      public void setListData(String data) {        dataLive.setValue(data);     }      public MutableLiveData<String> getData() {         return dataLive;     } } 

BlankFragment.class:

    @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container,                              Bundle savedInstanceState) {          listItemViewModel = ViewModelProviders.of(this, viewModelFactory)                 .get(VModel.class);         listItemViewModel.setData("");         return inflater.inflate(R.layout.fragment_blank, container, false);     } 
like image 775
Nikolas Bozic Avatar asked Feb 21 '18 19:02

Nikolas Bozic


People also ask

Why LiveData Observer is being triggered twice for a newly attached observer?

You set your observers within the onCreateView() hook method. After this point the lifecycle changes it state twice to come visible, on start and on resume .

Can two fragments use same ViewModel?

In android, we can use ViewModel to share data between various fragments or activities by sharing the same ViewModel among all the fragments and they can access everything defined in the ViewModel. This is one way to have communication between fragments or activities.

How do you pass data between fragments using ViewModel?

Use activity's scope to create an instance of the ViewModel in fragment so that all the fragments and activity now has a common ViewModel and have access to the same ViewModelStore . If the activity is re-created, it and all its fragments receive the same ViewModel instance that was created by the associated activity.

How does ViewModel retain data?

ViewModel objects are automatically retained during configuration changes so that data they hold is immediately available to the next activity or fragment instance. FYI: You can use ViewModel to preserve UI state only during a configuration change, nothing else as explained perfectly in this official doc.


1 Answers

Here is an example how i solve this problem .[TESTED AND WORKING]

 viewModel.getLoginResponse().observe(getViewLifecycleOwner(), new Observer<String>() {         @Override         public void onChanged(String response) {             if(getViewLifecycleOwner().getLifecycle().getCurrentState()== Lifecycle.State.RESUMED){                 // your code here ...             }          }     }); 
like image 107
Biplob Das Avatar answered Oct 20 '22 03:10

Biplob Das