Fragments - Do you have to use an Activity Wrapper around a fragment which comprises the whole Activity?

前端 未结 3 388
时光说笑
时光说笑 2021-02-04 01:54

Consider the sample app from developers.android.com

This describes using Fragments like so:

  • On a Phone you can use Fragment 1 on Activity A and fragment 2
相关标签:
3条回答
  • 2021-02-04 02:14

    More generically you could create a fragment container class:

    public class SingleFragmentActivity extends Activity {
    
        public static final String FRAGMENT_NAME = "fragmentName";
        public static final String FRAGMENT_ARGUMENTS = "fragmentArguments";
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            String fragmentName = getIntent().getStringExtra(FRAGMENT_NAME);
            Fragment fragment = Fragment.instantiate(this, fragmentName);
            Bundle fragmentArguments = getIntent().getBundleExtra(FRAGMENT_ARGUMENTS);
            fragment.setArguments(fragmentArguments);
            getSupportFragmentManager().beginTransaction().replace(android.R.id.content,fragment, "tag").commit();
        }
    }
    

    now you use this class to instantiate any fragment as a standalone activity:

    public void showFragmentAsActivity() {
        Intent intent = new Intent(this, SingleFragmentActivity.class);
        intent.putExtra(SingleFragmentActivity.FRAGMENT_NAME, MyFragment.class.getName());
        intent.putExtra(SingleFragmentActivity.FRAGMENT_ARGUMENTS,MyFragment.getArgumentsBundle("a string argument"));
        startActivity(intent);
    }
    
    0 讨论(0)
  • 2021-02-04 02:18

    Ah, found it here

    public class MainMenuHolder extends FragmentActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            // If not already added to the Fragment manager add it. If you don't do this a new Fragment will be added every time this method is called (Such as on orientation change)
            if(savedInstanceState == null)
                getSupportFragmentManager().beginTransaction().add(android.R.id.content, new MainMenuFragment()).commit();
        }
    }
    

    FragmentActivity allow's you to set the Fragment as the content of android.R.id.content which I assume is the android internal ID of the trunk view.

    With this method you still end up with an mostly redundant activity (If all you want is the Fragment acting as the Activity). But still, half as much fluff as having an activity and an XML file acting as a container.

    Any other answers would be appreciated!

    0 讨论(0)
  • 2021-02-04 02:35

    The online example doesn't fill in all the blanks. I'll try to answer your questions directly:

    "On the first example (the one with a phone) should you create an Activity with an xml file containing a single and an activity which only calls setContentView() on that xml and that's all?"

    You've started in the right place. But there's more to it than that. There's always more than one way to solve a problem in Android but a recommended way of generating the effect of having a dynamic number of fragments based on avail. real-estate is:

    1. Create layout XML files in /layout for the primary (default) targeted orientation/device/form-factor/SDK
    2. Create layout XML files for the smallest-width baseline for other targeted devices. You may also want to target other orientations, SDKs, etc.
    3. Each layout XML file will have it's own set of defined fragments
    4. In the Activity, check to see which fragments are present.

    Clearly an analogous strategy can be adopted for programmatic layouts.

    In your example in the original question (from Google's docs) you could have:

    • layout/main.xml :: this layout would only have Fragment 1
    • layout-sw600dp/main.xml :: this layout would have Fragments 1, 2

    Then in MainActivity.java you would check for the existence of each fragment. To do that you could use FragmentManager#findFragmentById() to have a check like: if findFragmentById() returns null for Fragment-2 then MainActivity knows the device has loaded layout/main.xml and only supports one fragment.

    Stepping 'back' from the example somewhat reveals that: prior to using Fragments you might have called Activity B from Activity A with startAcitityForResult(int). In the Fragment paradigm you probably only need to have a result from Fragment 2 cause something to happen in Fragment 1, so it's reasonable to have MainActivity be the gatekeeper for that. As you expand on the example you may see that in other apps, MainActivity may need to call other activities - for whatever reason. Perhaps you're targeting a large tablet with enough real estate for 3 fragments but on a handset that needs to be 3 activites. Things can get interesting but the Fragment API is fairly powerful.

    "Can you set a Fragment as an Activity or is a Wrapper always required when using fragments?"

    A Fragment is not an Activity. Indeed Fragments are loaded by Activities, so yes one might say a wrapper is always required. You're touching on aother subtle aspect of Fragments. Whereas Activities behave like MVC Controllers, Fragments could be called "mini-controllers" due to their lifecycle which both resembles and executes alongside an Activity. Again, the Fragment's lifecycle is contained inside ("wrapped by") the lifecycle of the Activity managing the Fragment. I recommend becoming familiar with the Fragment lifecycle documented at http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle.

    0 讨论(0)
提交回复
热议问题