2

I have an Activity which has a Save details button and a Viewpager which contains 4 fragments. The Fragments contains User details form. Once the Save button is clicked I need to get the data from all fragments and save the details. How to get the data entered by the user in all 4 fragments when Save button is clicked in the activity?

Leszek Jasek
  • 2,206
  • 1
  • 23
  • 30
deepThought
  • 699
  • 4
  • 26

1 Answers1

2

I just worked on an app that had the same use case. In addition, I had to save the data on a back navigation as well. The problem was a bit more difficult that I though it should have been. The problems came from the fact that not all the fragments in the ViewPager are guaranteed to be alive. They either may not have been started yet, or destroyed when the user paged off of them.

To solve the problem, I took inspiration from this blog post about handing back-press events. I had to modify it a bit to allow for any fragments that may be running and not just one.

public abstract class BackHandledFragment extends Fragment {
   protected BackHandlerInterface backHandlerInterface;
   public abstract String getTagText();
   public abstract boolean onBackPressed();

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      if(!(getActivity()  instanceof BackHandlerInterface)) {
         throw new ClassCastException("Hosting activity must implement BackHandlerInterface");
      } else {
         backHandlerInterface = (BackHandlerInterface) getActivity();
      }
   }

   @Override
   public void onResume() {
      super.onResume();
      backHandlerInterface.addRunningFragment(this);
   }

   @Override
   public void onPause() {
      super.onPause();
      backHandlerInterface.removeRunningFragment(this);
   }

   public interface BackHandlerInterface {
      public void addRunningFragment(BackHandledFragment backHandledFragment);
      public void removeRunningFragment(BackHandledFragment backHandledFragment);
   }
}

The Activity implements the interface and tracks the active fragments:

public class EditActivity implements BackHandledFragment.BackHandlerInterface
{
    private List<BackHandledFragment> listActiveFragments = new ArrayList<>

toolbar.setNavigationOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {

               // Notify each active fragment that the back was pressed, this will allow
               // them to save any data.
               for (BackHandledFragment bf : listActiveFragments) {
                  bf.onBackPressed();
               }
          }
@Override
   public void addRunningFragment(BackHandledFragment backHandledFragment) {
      listActiveFragments.add(backHandledFragment);
   }

   @Override
   public void removeRunningFragment(BackHandledFragment backHandledFragment) {
      listActiveFragments.remove(backHandledFragment);
   }();
}

Each fragment must extend BackHandledFragment:

public class DetailNetworkFragment extends BackHandledFragment {
   @Override
   public void onPause() {
      super.onPause();
      EventBus.getDefault().unregister(this);
      saveDataFields();
   }

   @Override
   public void onResume() {
      super.onResume();
      EventBus.getDefault().register(this);

   }

   @Override
   public String getTagText() {
      return TAG;
   }

   @Override
   public boolean onBackPressed() {
      saveDataFields();
      return false;
   }
}

The saveDataFields() is not too interesting. It just copies the data out of the UI views and saves them back to an object in the Activity.

Gary Bak
  • 4,746
  • 4
  • 22
  • 39