Android - Using fragment example

Wrote by: hoangnguyen     Create date: 07/02/2016     2287 views

You can think of a fragment as a sub-activity, which has its own lifecycle. A fragment must be embeded in an activity and its lifecycle is effected by the host activity's lifecycle.

 

In this tutorial, we guide you how to use fragment to create multi-pane UI. Specifically, we create two fragments, one to show list of articles, and another to show article detail.

PS: This project is developed in Android Studio 1.5.1 and tested on Android 4.0 (using Android Support Library v4)

 

1. XML layouts

Create following four XML layout files in "res/layout" folder:

      1. res/layout/activity_main.xml  - This is the main layout, contain two fragment.

      2. res/layout/fragment_article_list.xml - This is the left pane --> show list of articles

      3. res/layout/fragment_article_detail.xml - This is the right pane --> show article's detail content

      4. res/layout/article_item.xml - This is the layout for every item of list of articles

 

File  res/layout/activity_main.xml

<?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="horizontal"
    tools:context="com.hoanglinh.usingfragmentexample.MainActivity">

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

    <FrameLayout
        android:id="@+id/fragment_detail_article"
        android:layout_width="0dip"
        android:layout_height="match_parent"
        android:layout_weight="2"></FrameLayout>
</LinearLayout>

 

File res/layout/fragment_article_list.xml

<FrameLayout 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"
    tools:context="com.hoanglinh.usingfragmentexample.fragment.ArticleListFragment">

    <ListView
        android:id="@+id/list_articles"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/grey"></ListView>

</FrameLayout>

 

File res/layout/fragment_article_detail.xml

<FrameLayout 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"
    tools:context="com.hoanglinh.usingfragmentexample.fragment.ArticleDetailFragment">

    <TextView
        android:id="@+id/detail_article"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="@string/article_content_here"
        android:textSize="@dimen/article_content_size" />

</FrameLayout>

 

File res/layout/article_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/article_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="@dimen/article_text_size"
        android:text="@string/article_title_here"
        android:textColor="@color/textBlue"
        android:textSize="@dimen/article_text_size" />

</LinearLayout>

 

2. Activity

Create following activity class:

      1. MainActivity.java  - Main UI include two panes (list and detail)

 

File MainActivity.java 

package com.hoanglinh.usingfragmentexample;

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.widget.Toast;

import com.hoanglinh.usingfragmentexample.fragment.ArticleDetailFragment;
import com.hoanglinh.usingfragmentexample.fragment.ArticleListFragment;

/**
 * Created by NguyenNgocHoang on 07/02/2016.(Reference at:www.nguyenngochoang.info)
 */

public class MainActivity extends FragmentActivity implements ArticleListFragment.OnFragmentInteractionListener, ArticleDetailFragment.OnFragmentInteractionListener {
    private FragmentManager fragmentManager;

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

        ArticleListFragment articleListFragment = new ArticleListFragment();
        ArticleDetailFragment articleDetailFragment = new ArticleDetailFragment();

        fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        fragmentTransaction.add(R.id.fragment_list_article, articleListFragment);
        fragmentTransaction.add(R.id.fragment_detail_article, articleDetailFragment);

        fragmentTransaction.commit();
    }

    @Override
    public void onFragmentArticleListInteraction(int articleIndex) {
        ArticleDetailFragment articleDetailFragment = (ArticleDetailFragment) fragmentManager.findFragmentById(R.id.fragment_detail_article);
        if (articleDetailFragment != null) {
            articleDetailFragment.onShowArticelContent(articleIndex);
        }
    }

    @Override
    public void onFragmentArticleDetailInteraction(int articleIndex) {
        Toast.makeText(this, String.format("Your choose article %d", articleIndex), Toast.LENGTH_SHORT).show();
    }
}

 

3. Fragments

Create following two fragment classes:

     1. ArticleListFragment.java  - Left pane to show list of article

     1. ArticleDetailFragment.java  -  Right pane to show article detail 

 

File ArticleListFragment.java

package com.hoanglinh.usingfragmentexample.fragment;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.hoanglinh.usingfragmentexample.R;
import com.hoanglinh.usingfragmentexample.adapter.ArticleAdapter;

/**
 * Created by NguyenNgocHoang on 07/02/2016.(Reference at:www.nguyenngochoang.info)
 * <p/>
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link ArticleListFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link ArticleListFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class ArticleListFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private String[] articleTitles = {"Article 1", "Article 2", "Article 3", "Article 4", "Article 5", "Article 6", "Article 7", "Article 8", "Article 9", "Article 10"};
    private ListView listOfArticle;

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public ArticleListFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment ArticleListFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ArticleListFragment newInstance(String param1, String param2) {
        ArticleListFragment fragment = new ArticleListFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View parent = inflater.inflate(R.layout.fragment_article_list, container, false);
        listOfArticle = (ListView) parent.findViewById(R.id.list_articles);

        ArticleAdapter articleAdapter = new ArticleAdapter(getActivity().getBaseContext(), articleTitles);
        listOfArticle.setAdapter(articleAdapter);

        listOfArticle.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                onArticleItemSelected(position + 1);
            }
        });

        // Inflate the layout for this fragment
        return parent;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onArticleItemSelected(int articleIndex) {
        if (mListener != null) {
            mListener.onFragmentArticleListInteraction(articleIndex);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p/>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentArticleListInteraction(int articleIndex);
    }
}

 

File ArticleDetailFragment.java

package com.hoanglinh.usingfragmentexample.fragment;

import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.hoanglinh.usingfragmentexample.R;

/**
 * Created by NguyenNgocHoang on 07/02/2016.(Reference at:www.nguyenngochoang.info)
 * <p/>
 * A simple {@link Fragment} subclass.
 * Activities that contain this fragment must implement the
 * {@link ArticleDetailFragment.OnFragmentInteractionListener} interface
 * to handle interaction events.
 * Use the {@link ArticleDetailFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class ArticleDetailFragment extends Fragment {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    private TextView textViewArticleTitle;

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public ArticleDetailFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment ArticleDetailFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ArticleDetailFragment newInstance(String param1, String param2) {
        ArticleDetailFragment fragment = new ArticleDetailFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View parent = inflater.inflate(R.layout.fragment_article_detail, container, false);
        textViewArticleTitle = (TextView) parent.findViewById(R.id.detail_article);
        // Inflate the layout for this fragment
        return parent;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onShowArticelContent(int articleIndex) {
        textViewArticleTitle.setText(String.format("Article %d", articleIndex));
        if (mListener != null) {
            mListener.onFragmentArticleDetailInteraction(articleIndex);
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p/>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentArticleDetailInteraction(int articleIndex);
    }
}

 

4. Adapter

Create adapter to fill data for list of article:

      1. ArticleAdapter.java  -  Adapter to fill data into listview.

 

File ArticleAdapter.java

package com.hoanglinh.usingfragmentexample.adapter;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.hoanglinh.usingfragmentexample.R;

/**
 * Created by NguyenNgocHoang on 07/02/2016. (Reference at: www.nguyenngochoang.info)
 */
public class ArticleAdapter extends ArrayAdapter<String> {
    private Context mContext;
    private LayoutInflater mLayoutInflater;
    private String[] articleTitles;

    public ArticleAdapter(Context context, String[] articleTitles) {
        super(context, -1, articleTitles);
        mContext = context;
        mLayoutInflater = LayoutInflater.from(context);
        this.articleTitles = articleTitles;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = mLayoutInflater.inflate(R.layout.article_item, null);
            viewHolder = new ViewHolder();
            viewHolder.mTextViewAticleTitle = (TextView) convertView.findViewById(R.id.article_title);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.mTextViewAticleTitle.setText(articleTitles[position]);
        return convertView;
    }

    public static class ViewHolder {
        private TextView mTextViewAticleTitle;
    }
}

 

5. Demo

Run application.

 MainActivity.java  - screen display, show two panes, left one show list of article, another one show article detail.

 

Click on an article item on left pane (ArticleListFragment.java ), detail content will show on right pane  (ArticleDetailFragment.java ).

 

DOWNLOAD SOURCE CODE HERE

Nguyễn Ngọc Hoàng - Software Engineer
Ngoc Hoang Nguyen

If we cannot do anything, due to we haven't yet acquainted with it.

Go on will also reach to destination.

Follow me

Please wait