Tuesday, October 23, 2012

Android fragments example

This article provides an Android fragments example. The Android platform resizes the application UI to fit various screen sizes. All that the application developer needs to do is to provide resources (like images) for various form factors and the platform takes. But this is not always enough to optimize the user experience when the same application is being built for phones and tablets. Tablets offer more space which could be leveraged to show more content compared to what could be shown on the phone.

When Android applications are designed for phones and tablets it becomes necessary to make proper activity design decisions to optimize the user experience needs for tablets. Android platform has the fragments API which would be leveraged to separate distinct UI components and later combined in the desired layouts for both tablets and phones. Fragments helps in reuse of the UI components.

This example implements 2 fragments which are dynamically created using the fragment manager. This layout has the "fragment_container" element into which the created fragments would be loaded.

Create a layout XML for the main activity.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"/>

</LinearLayout>

Create a layout XML for the list fragment. Note that we have used "@android:id/list" as identifier.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

 <ListView
     android:id="@android:id/list"
     android:layout_width="match_parent"
     android:layout_height="wrap_content" >
 </ListView>

</LinearLayout>

Finally create a layout file for the details fragment.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="24dp"
android:text="@string/details" />

</RelativeLayout>

Now that all layouts are in place we need to tie them together using fragments. In the onCreate method of the MainActivity we create an instance of MyListFragment instance and add to the fragment_container using the FragmentManager and FragmentTransaction APIs. It also necessary to commit the transaction.

Also note that we are implementing MyListFragmentInterface and passing it to the list fragment. This is necessary for the fragment to communicate list item selection back to the main activity. Also of significance in itemSelected() method is addToBackStack method to handle the back navigation.
package com.sourcetricks.fragmentsexample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;

public class MainActivity extends FragmentActivity implements MyListFragmentInterface {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create the initial list fragment
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        Fragment fragment = new MyListFragment(this);
        fragmentTransaction.add(R.id.fragment_container, fragment, "MYLIST");
        fragmentTransaction.commit();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    public void itemSelected(String id) {
         // Switch to details fragment
         FragmentManager fragmentManager = getSupportFragmentManager();
         FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
         Fragment fragment = new MyDetailsFragment();
         fragmentTransaction.replace(R.id.fragment_container, fragment, "MYDETAILS");
         fragmentTransaction.addToBackStack(null);
         fragmentTransaction.commit();
    }
}

The callback interface looks as below.
package com.sourcetricks.fragmentsexample;

public interface MyListFragmentInterface {
 public void itemSelected(String id);
}

We now move on to the list fragment implementation. Note the implementation of onCreateView which inflates the view.
package com.sourcetricks.fragmentsexample;

import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MyListFragment extends ListFragment {

 private static MyListFragmentInterface mCallback = null;
 private String[] mListItems = { "Apple", "Orange", "Pear", "Peach", "Banana" }; 

 public MyListFragment() { 
 }

 public MyListFragment(MyListFragmentInterface callback) {
  mCallback = callback;
 }

 @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
               // Inflate the layout for this fragment
               View view =  inflater.inflate(R.layout.my_list_fragment, container, false); 

               setListAdapter(new ArrayAdapter(getActivity(), 
          android.R.layout.simple_list_item_1,
          mListItems));

               return view;
        }

 @Override
 public void onListItemClick(ListView l, View v, int position, long id) {
  mCallback.itemSelected(mListItems[position]);  
 }
}

Finally, the implementation of details fragment which is straightforward.
package com.sourcetricks.fragmentsexample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyDetailsFragment extends Fragment {

 public MyDetailsFragment() { 
 }

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view =  inflater.inflate(R.layout.my_details_fragment, container, false);         
        return view;
    }
}

0 comments :

Post a Comment

Contact Form

Name

Email *

Message *

Back to Top