Skip to content Skip to sidebar Skip to footer

How To Pass Selected Item From Listfragment To Previous Fragment After Calling Popbackstack()?

I have prepared a very simple test case with 1 activity and 2 fragments for my question: MainActivity.java (stores selected item in shared preferences) MyMainFragment.java (displa

Solution 1:

As I see it, you already have a reasonable first part to the answer (suggestion by corsair992 - pass the value from the item selected) the second part is how do you handle the back key.

There are a few ways of doing that (listening to the back stack etc.) but the one I have used most fequently is:

declare a back key listener interface:

publicinterfaceBackKeyListener {
   boolean onBackPressed();
}

in your main activity add the following:

importBackKeyListener;
voidonBackKeyPressed() {
   boolean backKeyHandled = false;
   Fragment activeFragment = getActiveFragment();
   if (activeFragment instanceofBackKeyListener) {
      backKeyHandled = ((BackKeyListener) activeFragment).onBackKeyPressed();
   }
   if (!handled) {
      // If should process back key normally, pass to super..super.onBackKeyPressed();
   }
}

FragmentgetActiveFragment() {
   // I'm assuming you place all your fragments here, if not..// alter to suitreturngetFragmentManager().findFragmentById(R.id.root);
}

in MyListFragment add the following:

import BackKeyListener;

classMyListFragmentextendsFragment(orsomething) implementsBackKeyListenerpublicbooleanonBackPressed() {
  // User pressed back, select default item..
  ((MainActivity) getActivity()).itemSelected(selectedItem);

  // In this case, prevent normal back processing or// you might get a double backstack pop.returntrue;
}

Using an interface on the fragment allows you to "not care" what the active fragment is. If it implements the BackKeyListener, the MainActivity will call it when the back key is pressed. This gives you the option of passing a value back to the activity.

Solution 2:

Is your first fragment still kept in memory when this happens? I assume so. This means you could use a SharedPreferences.OnSharedPreferenceChangeListener. Just make MyMainFragment implement the interface and then use the registerOnSharedPreferenceChangeListener to monitor for changes. Don't forget to unregister, though!

An even better idea might be to register your activity as the listener and make it pass that data to MyMainFragment when it displays it again.

Solution 3:

First of all, you can use SharedPrefences inside UI thread, i.e. inside fragments. This common misconception takes root from the time when there was only commit() method. Now we have apply() working asynchronously and get*() using cached data.

Second, the simplest way to solve your problem, without juggling with SDK, will be to notify Activity of items selection in your second fragment (for example, inside your fragment: ((MainActivity)getActivity()).setSelectedItem(itemId);) and get this value on your first fragment's onResume() (for example, ((MainActivity)getActivity()).getSelectedItem();). Of course you should check this value for null in case nothing was selected.

Solution 4:

Assign a tag to MyMainFragment, suppose it will be MY_MAIN_FRAGMENT_TAG. Add this code to your itemSelected method:

FragmentmyMainFragment= getFragmentManger.findFragmentByTag("MY_MAIN_FRAGMENT_TAG");
if (null != myMainFragment) {
    Bundleargs=newBundle();
    myMainFragment.getArguments().putInt("selectedItem", index);
    getFragmentManager().popBackStack();
}

Then in your MyMainFragment override onViewStateRestored() method:

@Override
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    super.onViewStateRestored(savedInstanceState);
    mSelectedTextView.setText(String.valueOf(getArguments.getInt("selectedItem")));
}

Probably you will need some additional checks if null != getArguments() and set apropriate value to a TextView.

Solution 5:

A solution is to use setTargetFragment/getTargetFragment approach. With this approach you can use just your Fragments without the Activity and SharedPreferences help. In your MyMainFragment, when the user click the button "Select item..." you can use your callback selectedButtonClicked() as :

publicvoidselectedButtonClicked() {

Fragment fragment = MyListFragment.newInstance(index);

//Set the TargetFragment

fragment.setTargetFragment(MyMainFragment.this, MyListFragment.REQUESTCODE)

    getFragmentManager().beginTransaction()
    .addToBackStack(null)
    .replace(R.id.root, fragment, LIST)
    .commit();
 }

You have to define the callback onActivityResult of the MainFragment:

publicvoidonActivityResult(int requestCode, int resultCode, Intent data){

    if(requestCode == MyListFragment.REQUESTCODE){
         f.setText("Selected index: " + intent.getInt("INDEX");
    }
}

In the MyListFragment once the user selects an item, you can call your callback itemSelected()

publicvoiditemSelected(int index) {

Intenti=newIntent();    
i.putExtraInt("INDEX",index);
getTargetFragment.onActivityResult(MyListFragment.REQUESTCODE,Context.Result_OK,i);
    getFragmentManager().popBackStackImmediate();

} 

Post a Comment for "How To Pass Selected Item From Listfragment To Previous Fragment After Calling Popbackstack()?"