Mcorv
Mcorv

Reputation: 171

Start Fragment from Activity

I'm able to start a Fragment from an Activity. However Im worried about potential problems with my implementation.

I have two fragments, FragmentA and FragmentB And I have 3 activity classes, Activity1, Activity2, ResultActivity

public class NavigationTabs extends FragmentActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_tabs_2);

    FragmentStatePagerAdapter adapter = new MyTabs(getSupportFragmentManager());
    ....
    ....
 }

 static class MyTabs extends FragmentStatePagerAdapter {
    public MyTabs(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch(position)
        {
                case 0:

                     FragmentA FragA = new FragmentA();  
                     return FragA;

                 case 1:

                     FragmentB FragB = new FragmentB();  
                     return FragB;
      ......
      ......
      }
  }

^How I call FragmentA and FragmentB

FragmentA starts Activity1 via an intent.

    Intent intent = new Intent(getActivity(), Activity1.class);
    startActivity(intent);

Activity1 then passes the results of a counter to ResultActivity

ResultActivity starts(or returns to) FragmentA and sets SharedPreferences via onClick like this

public void onClick(View v) {
   if(v.getId()== R.id.button_1){
      SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
      Editor edit = sp.edit();
      edit.putInt(passedSavePref, counter);
      edit.commit();

      finish();
}
}

FragmentB starts Activity2 via an intent.

Intent intent = new Intent(getActivity(), Activity2.class);
    startActivity(intent);

Activity2 then passes the results of a counter to ResultActivity

ResultActivity starts(returns to) FragmentB and sets SharedPreferences via onClick like this

   public void onClick(View v) {
   if(v.getId()== R.id.button_1){
      SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
      Editor edit = sp.edit();
      edit.putInt(passedSavePref, counter);
      edit.commit();

      finish();
}
}

This all works for my needs. GC seems fine, its freeing and allocating memory.

ResultActivty returns to the correct Fragment, and it sets the SavedPreferences correctly.

Yet it seems very bad implementation. For starters, while searching through other questions I've read, "Don't start an Activity directly from a Fragment" the poster also linked to the proper implementation here https://developer.android.com/guide/components/fragments.html#EventCallbacks

I've tried calling Activity1 from FragmentA like this, but I don't really see a difference in behavior or performance

  Intent intent = new Intent(getActivity(), Activity1.class);
  startActivity(intent);
  getActivity().getSupportFragmentManager().popBackStack();

So my question is, do I need to finish/remove FragmentA when I start Activity1, then start FragmentA again from ResultActivityusing something like

 FragmentTransaction transaction = getFragmentManager().beginTransaction();

Thanks in advance.

EDIT So what I was trying to was to either kill/finish/pop FragmentA so that I could re-start it from ResultActivity. The reason I was tying to do that was because my savedPreferences were not loading when I was going back to FragmentA from ResultActivity.(well they were saving and loading correctly, but I couldn't see them)

As I understand it from the docs,Fragments go on pause. So calling my loadPreferences method onResume(); loaded my SavedPreferences.

Not marking this as an answer, because I did not implement any of the standard/proper practices of dealing with Fragments popBackStack(); FragmentTransactions etc

Upvotes: 1

Views: 9501

Answers (1)

NameSpace
NameSpace

Reputation: 10177

  1. Quote: "Don't start an Activity directly from a Fragment"

I read the poster who wrote this, and I strongly disagree. His rationale is that it reduces the modularity of the fragment, and he believes you should impelment an interface to call back to the activity.

I disagree. It doesn't reduce modularity, in fact it increases it. Why implement a layer of abstraction to do something the fragment is intended to do in every implementation? Why re-write the same code in every activity, when it can be modularized in the fragment? In fact fragments wouldn't have their own specialized functions for starting activities if this was against design principles.

For instance, if you start an activity using fragment.startAcitivtyForResult(), the fragment is put directly as the onActivityResult receiver. Not so if you use your activity instance to directly start the new activity.

  1. You do not need to remove framgents before starting a new Activity

Android will pause/stop your fragments, and potentially destroy them and the underlying activity as well if need be. Android is constantly destroying and recreating activities and fragments, like every time you change the orientation on your screen - the default settings has your activity and fragments commit mass suicide.

This is why functions like OnSaveInstanceState() are so important, because they let your activities and fragments return to a saved state. The general rule of android programming is your activity / fragments should be able to respond to spontaneous death gracefully.

Upvotes: 1

Related Questions