Android Working with Fragments Part three

If you are not Familiar with Fragments please check my Android Working with Fragment post.

In my earlier post, i described how to replace the fragments in container containing one fragment at a time to check refer here Android Working with Fragments Part Two

In this post, I will describe how to add the fragments in the container than on pressing the hard Back Button restore to previous Fragment. In short, how to manage the Fragments in the container and implementing the back button pressed method of activity to push the user to restore to previous UI or previous Fragment on Back button.

So,Let’s Start:-

  1. First, we will create a Fragment layout containing two buttons and Textview, one button to add the fragment to the container, other to remove the fragment from container and Textview to show help text.
  2.  Then we will use this layout and create fragment and implement the functionality to add the fragment and for another button to remove the fragment.
  3. Then we will create an Activity layout containing Framelayout which will act as a Container .

Fragment layout as fragment_first.xml

<?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">

    <Button
        android:id="@+id/back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Remove Fragment from Container"
        android:layout_marginTop="20dp"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_marginTop="50dp"
        android:text="Click on Below Button To add another fragment to the container"/>

    <Button
        android:id="@+id/addfragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Add another fragment"
        />

</LinearLayout>

Fragment as FirstFragment

package com.coderzpassion.fragmentssample;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by coderzpassion on 13/06/16.
 */
public class FirstFragment extends Fragment {
    public final ScheduledExecutorService worker =
            Executors.newSingleThreadScheduledExecutor();
    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.fragment_first, container, false);
        Button title=(Button)view.findViewById(R.id.addfragment);
        title.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirstFragment firstFragment = new FirstFragment();
              final  FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.add(R.id.frame_container,firstFragment).addToBackStack("firstfragment").commit();

          // slightly added a delay as it takes some time to add fragment to container
                // then checked for no of fragments in the container
                Runnable r = new Runnable() {
                    @Override
                    public void run() {
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getActivity(), "Total Fragments in Container " + fragmentManager.getBackStackEntryCount(), Toast.LENGTH_SHORT).show();
                            }
                        });

                    }
                };
                worker.schedule(r, 1000, TimeUnit.MILLISECONDS);
            }
        });


        Button back=(Button)view.findViewById(R.id.back);
        back.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // created s static method in Actvity to remove the current fragment from Container
                ((AddingFragmentContainer)getActivity()).popSingleFragment();
            }
        });
        return view;

    }



}

Activity layout as activity_addfragment.xml

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

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

Activity as AddingFragmentContainer

package com.coderzpassion.fragmentssample;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by coderzpassion on 13/06/16.
 */
public class AddingFragmentContainer extends FragmentActivity {

    FragmentManager fragmentManager;
    FragmentTransaction transaction;
  public FirstFragment firstFragment;
    public final ScheduledExecutorService worker =
            Executors.newSingleThreadScheduledExecutor();

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

         firstFragment=new FirstFragment();
        fragmentManager = getSupportFragmentManager();
        transaction=fragmentManager.beginTransaction();

          transaction.add(R.id.frame_container, firstFragment).addToBackStack("firstfragment").commit();

        // slightly added a delay as it takes some time to add fragment to container
        // then checked for no of fragments in the container
        Runnable r=new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(AddingFragmentContainer.this, "Fragments in Container " + fragmentManager.getBackStackEntryCount(), Toast.LENGTH_SHORT).show();
                    }
                });

            }
        };

        worker.schedule(r, 1000, TimeUnit.MILLISECONDS);
    }


    @Override
    public void onBackPressed() {


        if(fragmentManager.getBackStackEntryCount()>0)
        {
            fragmentManager.popBackStack();
            Log.e("poping back"," Done");
        }
        else
        {
            super.onBackPressed();
        }

    }

    public void popSingleFragment()
    {
        if(fragmentManager.getBackStackEntryCount()>0)
        {
            fragmentManager.popBackStack();
            Log.e("poping back"," Done");
        }
        else
        {
            super.onBackPressed();
        }
        // slightly added a delay as it takes some time to add fragment to container
        // then checked for no of fragments in the container
        Runnable r=new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(AddingFragmentContainer.this, "Fragments Remaining in Container " + fragmentManager.getBackStackEntryCount(), Toast.LENGTH_SHORT).show();
                    }
                });

            }
        };

        worker.schedule(r, 1000, TimeUnit.MILLISECONDS);

       }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coderzpassion.fragmentssample" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
  
        <activity android:name=".AddingFragmentContainer">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Output

addingfragmentstocontainer    managingbackbuttonforfragments   removingfragmentsfromcontainer

Android Working with Fragments Part Two

If you are not Familiar with Fragments please check my Android Working with Fragment  post.

In this post, I will be describe working with fragments using a Container layout i.e having a container, and replacing the fragments in the container according to user actions. In brief, we will have one fragment in the container at a time when user clicks on the button we replace the current fragment with the required fragment.

So,Let’s Start:-

  1. First we will create a Fragment layout containing textview and Fragment to recieve the argument and set to Textview.
  2. Then we will create another Fragment using the same layout as to describe we can use the Required Fragment.
  3. Then we will create a Activity layout containing FrameLayout which will act as a Container and four buttons on which click we will replace the fragments in the container.

Fragment layout as fragment_container.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="40px"
            android:text="FirstFragment"
            android:layout_centerInParent="true"
            android:id="@+id/titlename"/>
    
</RelativeLayout>

ContainerFragment

package com.coderzpassion.fragmentssample;

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.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

/**
 * Created by coderzpassion on 13/06/16.
 */
public class ContainerFragment extends Fragment {

    String maintitle="";


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        maintitle=getArguments().getString("title");
    }

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.fragment_container, container, false);

        TextView title=(TextView)view.findViewById(R.id.titlename);
        title.setText(maintitle);

        return view;

    }
}

ContainerTwoFragment

package com.coderzpassion.fragmentssample;

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;

/**
 * Created by coderzpassion on 21/06/16.
 */

public class ContainerTwoFragment extends Fragment {

    String maintitle="";


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        maintitle=getArguments().getString("title");
    }

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.fragment_container, container, false);

        TextView title=(TextView)view.findViewById(R.id.titlename);
        title.setText(maintitle);

        return view;

    }
}

Activity layout as activity_container

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

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
        android:weightSum="4">

        <Button
            android:id="@+id/first"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="First"/>

        <Button
            android:id="@+id/second"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Second"/>

        <Button
            android:id="@+id/third"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="third"/>

        <Button
            android:id="@+id/fourth"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Fourth"/>

    </LinearLayout>

</RelativeLayout>

FragmentContainerActivity

package com.coderzpassion.fragmentssample;

import android.app.Activity;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.view.View;
import android.widget.Button;

/**
 * Created by coderzpassion on 13/06/16.
 */
public class FragmentContainerActivity extends FragmentActivity implements View.OnClickListener{


    Button first,second,third,fourth;
    Fragment fragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_container);
        first=(Button)findViewById(R.id.first);
        second=(Button)findViewById(R.id.second);
        third=(Button)findViewById(R.id.third);
        fourth=(Button)findViewById(R.id.fourth);
        first.setOnClickListener(this);
        second.setOnClickListener(this);
        third.setOnClickListener(this);
        fourth.setOnClickListener(this);

        //this fragment will be called first when application runs
        ContainerFragment fragment1=new ContainerFragment();
        Bundle b=new Bundle();
        b.putString("title", "Welcome To Fragment Tutorials! CoderzPassion Click on Buttons To Replace Current fragment in Container");
        fragment1.setArguments(b);
        if (fragment1 != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.frame_container, fragment1).commit();
        }

    }


    //on click of buttons
    @Override
    public void onClick(View v) {

        switch (v.getId())
        {

          case  R.id.first:
              fragment=new ContainerFragment();
              Bundle b=new Bundle();
              b.putString("title","first");
              fragment.setArguments(b);
            if (fragment != null) {
                FragmentManager fragmentManager = getSupportFragmentManager();
                fragmentManager.beginTransaction()
                        .replace(R.id.frame_container, fragment).commit();
            }
            break;

            case  R.id.second:
                fragment=new ContainerFragment();
                Bundle b1=new Bundle();
                b1.putString("title","second");
                fragment.setArguments(b1);
                if (fragment != null) {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.frame_container, fragment).commit();
                }
                break;

            case  R.id.third:
                fragment=new ContainerTwoFragment();
                Bundle b2=new Bundle();
                b2.putString("title","third");
                fragment.setArguments(b2);

                if (fragment != null) {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.frame_container, fragment).commit();
                }
                break;

            case  R.id.fourth:
                fragment=new ContainerTwoFragment();
                Bundle b3=new Bundle();
                b3.putString("title","fourth");
                fragment.setArguments(b3);

                if (fragment != null) {
                    FragmentManager fragmentManager = getSupportFragmentManager();
                    fragmentManager.beginTransaction()
                            .replace(R.id.frame_container, fragment).commit();
                }
                break;
        }
    }
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coderzpassion.fragmentssample" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity android:name=".FragmentContainerActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Output

androidfragmentsusingcontainer   androidaddingfragmentstocontainer   androidreplacingthefragmentincontainer

How to implement Fragments in Android.

A fragment is a part or portion of Activity. It is also known as sub-activity.

The Primary classes related to fragment are:

  1. android.app.Fragment: Base class for fragment definitions.
  2. android.app.FragmentManager: Class for interacting with fragments within the activity.
  3. android.app.FragmentTransaction: Class for performing operations like adding or replacing the fragments.

Google also provides compatibility support v4 package for Fragments.Its main classes are :

  1. android.support.v4.app.FragmentActivity: The base class for all activity to containing fragment related features.
  2. android.support.v4.app.Fragment: The base class for all fragment operations.
  3. android.support.v4.app.FragmentManager: The class for interacting with fragments in activity.
  4. android.support.v4.app.FragmentTransaction: The class for performing fragments operations like adding,replacing the fragment.

Note: To use compatibility support v4 package your activity must use FragmentActivity as a Base Class.

if you are already familiar with fragments check Android Working with Fragments Part Two

Main Features of Fragment:-

  1. A Fragment has its own layout and lifecycle similar to Activity.
  2. A Fragment can be added or removed at runtime thus making UI look appropriate.
  3. There can many fragments in one activity.
  4. Fragment are reusable, Fragments must be embedded in activities.

So, Let’s by taking an example:

Steps:-

  1. Layout for fragment named as data_fragment.
  2. Create a Fragment named as DataFragment using above layout.
  3. Layout for fragment named as list_fragment.
  4. Create a Fragment named as Listing Fragment using above layout.
  5. Now create a layout for Activity named as activity_main containing above two Fragments we created.
  6. Now Create an Activity named as MainActivity and run the Project.

Open AndroidStudio or Eclipse and create an android application project and follow the instructions and then click on finish.

  1. First of all, we will create a layout for fragment as data_fragment
<?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:gravity="center"
    android:background="#5ba4e5"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="40px"
        android:textColor="#ffffff"
        android:layout_gravity="center"
        android:id="@+id/mainitems"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textColor="#ffffff"
        android:textSize="30px"
        android:id="@+id/subitems"/>

</LinearLayout>

2. Create Fragment class DataFragment

package com.coderzpassion.fragmentssample;

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;

/**
 * Created by coderzpassion on 13/06/16.
 */
public class DataFragment extends Fragment {

    TextView text,vers;

    @Override

    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.data_fragment, container, false);
        text= (TextView) view.findViewById(R.id.mainitems);
        vers= (TextView)view.findViewById(R.id.subitems);


        return view;

    }
    public void change(String txt, String txt1){
        text.setText(txt);
        vers.setText(txt1);

    }

}

3. Create a layout named as list_fragment

<?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:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/listfragment" />
</LinearLayout>

4. Create a Fragment named as ListingFragment

package com.coderzpassion.fragmentssample;

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.ArrayAdapter;
import android.widget.ListView;

/**
 * Created by coderzpassion on 13/06/16.
 */
public class ListingFragment extends Fragment  implements AdapterView.OnItemClickListener{


    String[] MainItems = new String[] { "main item 1","main item 2","main item 3","main item 4","main item 5","main item 6","main item 7","main item 8","main item 9" };
    String[] SubItems = new String[]{"sub item 1","sub item 2","sub item 3","sub item 4","sub item 5","sub item 6","sub item 7","sub item 8","sub item 9"};
    ListView list;

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container, Bundle savedInstanceState) {
        View view =inflater.inflate(R.layout.list_fragment, container, false);
         list=(ListView)view.findViewById(R.id.listfragment);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
                android.R.layout.simple_list_item_1, MainItems);
        list.setAdapter(adapter);
        list.setOnItemClickListener(this);
        return view;

    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        DataFragment txt = (DataFragment)getFragmentManager().findFragmentById(R.id.fragment2);
        txt.change(MainItems[position], "SubItems : " + SubItems[position]);
    }

}

5. Create a layout named as activity_main

<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"
    android:weightSum="2"
    >
    
            <fragment
                android:layout_height="match_parent"
                android:layout_width="0dp"
                android:layout_weight="1"
                class="com.coderzpassion.fragmentssample.ListingFragment"
                android:id="@+id/fragment"/>
            <fragment
                android:layout_width="0dp"
                android:layout_height="match_parent"        
                android:layout_weight="1"
                class="com.coderzpassion.fragmentssample.DataFragment"
                android:id="@+id/fragment2"/>


    </LinearLayout>

6. Create an Activity class named as default MainActivity.

package com.coderzpassion.fragmentssample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

Now run this Project you will find the Output like this

androidfragments  androidworkingwithfragmentsexample   workingwithfragments