Multi-platform fragments, Part II

In Part I I describe a pretty well-known way of using resources to make an application look good on a variety of devices.  It works pretty well as far as it goes, but 20% of Android users out there are still running Eclair, and some of them are using HVGA screens.  For them we’ll need, reluctantly, to back away from fragments.  It turns out that that isn’t so bad either.

First move the existing layout directories, from Part I, “layout” and “layout-port” so that they apply only to large screens.  Rename them “layout-large” and “layout-large-port”.  The application will continue to behave as it did in Part 1, as long as the device screen qualifies as “large”.   BTW, here’s some handy code that will let you know what kind of screen Android thinks it is dealing with:

Configuration config = getResources().getConfiguration();

Log.d(TAG, "Orientation: " + config.orientation);

Log.d("TAG, "Size: " + (config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK));

Here’s a new version of the main layout.  Put it in “layout”, the default for normal (and small) platforms:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

 

<ListView

android:id="@+id/contacts"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_weight="2"

/>

</LinearLayout>

The trick is that this version is completely missing the FrameLayout that the previous versions used to position the fragment. Here’s a new version of onCreate that determines whether to use fragments, or not:

@Override

public void onCreate(Bundle state) {

super.onCreate(state);

 

setContentView(R.layout.main);

 

final boolean useFrag

= null != findViewById(R.id.contact_detail);

 

if (useFrag) { installFragment(); }

 

//...

}

It only installs the visible fragment showing the contact details if there is a place to put it.  On small screens, then, no fragment will get created.

There’s just one more piece: what to do when there’s a click in the list of contacts.  In the old version we created a new fragment and put it on the stack.  In this version, though, we either stack a fragment or a new activity, depending on whether there’s a place to put the fragment or not.  The activity’s onClickHandler calls launchDetails to navigate to the contact details, how ever they are represented in the UI.  It looks like this:

void launchDetails(int pos, boolean useFrag) {

//... get the name and id from a cursor

 

if (useFrag) { stackFragment(id, name); }

else { stackActivity(id, name); }

}


private void stackFragment(String id, String name) {

FragmentTransaction xact

= getSupportFragmentManager().beginTransaction();


xact.replace(

R.id.contact_detail,

ContactDetailFragment.newInstance(id, name),

FRAG_TAG);

xact.addToBackStack(null);

xact.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

xact.commit();

}


private void stackActivity(String id, String name) {

Intent intent = new Intent();

intent.setClass(this, ContactDetailActivity.class);

intent.putExtra(ContactDetails.TAG_ID, id);

intent.putExtra(ContactDetails.TAG_CONTACT, name);

startActivity(intent);

}

That’s it!  When this application runs on a small screen, it will launch a new activity into the back-stack, instead of a new fragment.  It looks like this:

No frags1 No frags2

This idea comes from one of Diane Hackborne’s posts on the Android Developer’s blog.  It’s so tasty, though that it bears repeating.  The rest of the docs for fragments are here.

There are a couple of other things about this app that are worthy of note.  First, as is, it will treat an xlarge screen like a small or a normal one.  That’s probably not right.  Also, I suppose, how it is that the demo has an Activity and a Fragment with the same behavior could use a little explanation.

You can find all the code for this demo application here.

About bmeike
Android developer and evangelist in Oakland, CA

4 Responses to Multi-platform fragments, Part II

  1. Vishal S says:

    Great work, i have referred this article to develop my first android app. Thanks a lot. Please fix the link for the source download.

  2. Christian Franco says:

    Great Post! but the link doesn’t exists for download

Leave a reply to Christian Franco Cancel reply