Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android fragment navigation for tablets - single or multiple activities?

I'd like to achieve navigation like this (picture below), where fragments A,B,C,D represent navigation down the application's information hierarchy.

On the phone only one fragment will be visible, and on the tablets there are two fragments visible.

All of the tutorials and documents I've seen (for example this and this) mention Master-Detail view, where it seems there is a master fragment on the left and a detail view on the right, but nobody seems to specify how to drill deeper from the detail.

enter image description here

In fact, GMail app for tablets works as my own app. Let's say that fragment A is list of accounts and folders, fragment B is list of e-mails and fragment C is the conversation itself.

This screen is configuration with fragments A and B enter image description here

This screen has fragments B and C enter image description here

The question is: Should I implement this with a single Activity, where

  • for phones I will have one FrameLayout for the fragments
  • for tablets I will have two FrameLayouts for the 'left' and 'right' fragment?

If so, how will I insert the new fragments? In FragmentTransaction I have two actions available - add() and replace().

  • If I use add(), then the fragments below seem to be alive (they don't enter paused state) and retain their complete state (but presumably waste some resources) (so in Fragment D, all of C, B and A will still be there), and on the back button the scroll state and loaded data will still be there
  • If I use replace(), then the previous fragment will be removed, so there will be only one (on the phone) fragment on the top in any moment, and on the back button the transaction will get reversed, old fragment added back, but it won't remember its previous state

None of these options seems right to me. The tutorials use replace() in the FragmentTransaction - but how do they restore the state of the previous fragment, for example in the GMail app for phone the fragment B is loaded from the server with endless scrolling, then when I replace it with fragment C and go back, B should appear back where it was left off, right?

I really don't know what to do or where to look, please advise.

like image 888
Axarydax Avatar asked May 01 '14 18:05

Axarydax


1 Answers

use only 1 activity, but with different FragmentTransactions for each of them. Use a LinearLayout as the root of your activity, let's call it R.id.content and create a new XML values as follows in:

  • /values/device.xml

    <item type="bool" format="boolean" name="isPhone">true</item>

  • /values-sw600dp/device.xml

    <item type="bool" format="boolean" name="isPhone">false</item>

then your transactions will be like:

  FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
  Frag_C f = new Frag_C();
  if(getResources().getBoolean(R.bool.isPhone)){ // phone
     ft.replace(R.id.content, f, Frag_C.TAG);
  }else { // tablet
     Fragment left = getSupportFragmentManager().findFragmentByTag(Frag_A.TAG);
     Fragment right = f;
     ft.hide(left);
     ft.add(R.id.content, right, FRAG_C.TAG);
  }
  ft.addToBackStack(null).commit();

and as a final note, when inflating each fragment, you MUST set the layout parameters WEIGHT of the LinearLayout to control the width of the fragments. Something like that:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
   View v = inflater.inflate(layoutId(), container, false);
   ((LinearLayout.LayoutParams) v.getLayoutParams()).weight = 1;
}

so fragA weight would be 1, then B=2, then C=4, then D=8 (for example). So the left fragment will be 33% width n the right will be 66%. Vary the values however you need.

If you want to know how to animate those transactions, please refer to this answer I gave before https://stackoverflow.com/a/14155204/906362

like image 194
Budius Avatar answered Oct 14 '22 16:10

Budius