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); }
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 .
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.
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.
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.
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 ... } } });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With