How to set fragments in tags in Android

- Andrés Cruz

En español
How to set fragments in tags in Android

Download

One of the great objectives in software development in general is that the applications to be carried out are modular and can be easily reused, adapt new modules, etc.; one way to achieve this in Android, which is our case of interest in this post, is with fragments, of which we can say that:

A fragment represents a slice, section, or module of a user interface in an activity:

fragments en android

Although we will see that each time we encapsulate the application more and more, the most common possibilities for communication between the modules and, therefore, for building the application in general, are closed to us; one of these cases is when we want to list several fragments in the same activity (remember that an activity can contain one or more fragments), one way to do this is through tabs; at this point we will realize that our fragment is already encapsulated within another module (or rather an element provided by the Android API to create slider views); All this brings us a higher level of complexity of the already complex handling that Android has when programming an application (for example, the instance of the activity <<actitity>> that we must use in a large number of functions as a mandatory parameter :

Ejemplo de un código con el objeto Activity

In this post we will see a simple case of how we can establish several fragments in tags and in this way create slider views, as well as being able to switch from one fragment to another whenever we want.

Creating our slider views with Tags and snippets

The experiment consists of creating three fragments and linking them directly to the tags that will contain them; In addition, we can easily replace the content of the fragment in any location we want, as we will see later.

Fragment 1

<?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"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:background="#FF0000"
   tools:context="com.insta.andre.tagfragment.MainActivity">

  
   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:text="UNO"
       android:gravity="center_vertical|center_horizontal"
       android:textSize="50dp"/>
</RelativeLayout>

Fragment 2

<?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"
   android:background="#00FF00"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.insta.andre.tagfragment.MainActivity">


   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center_vertical|center_horizontal"
       android:text="DOS"
       android:textSize="50dp" />

   <Button
       android:id="@+id/cambiar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:text="Cambiar a fragment 3" />
</RelativeLayout>

Fragment 3

<?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"
   android:background="#0000FF"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.insta.andre.tagfragment.MainActivity">

   <TextView
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:gravity="center_vertical|center_horizontal"
       android:text="TRES"
       android:textSize="50dp" />

   <Button
       android:id="@+id/cambiar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:text="Cambiar a fragment 2"
       android:layout_alignParentBottom="true"/>

</RelativeLayout>

How we see the content of the fragments are practically the same except for the content of the TextView and a couple of fragments have a button that we will configure later; from our activity we will have to define a layout like the following:

<?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"
   tools:context="com.insta.andre.tagfragment.MainActivity">

   <TabHost android:id="@android:id/tabhost"
       android:layout_width="match_parent"
       android:layout_height="match_parent" >

       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent" >

           <FrameLayout
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:padding="5dp"
               android:layout_weight="1"
               android:id="@android:id/tabcontent" >

               <FrameLayout android:id="@+id/tab1"
                   android:orientation="vertical"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent" >
               </FrameLayout>

               <FrameLayout android:id="@+id/tab2"
                   android:orientation="vertical"
                   android:layout_width="match_parent"
                   android:layout_height="match_parent" >
               </FrameLayout>
           </FrameLayout>

           <TabWidget
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:layout_weight="0"
               android:layout_marginBottom="-4dp"
               android:id="@android:id/tabs" />
       </LinearLayout>
   </TabHost>

</RelativeLayout>

As you can see in the following image and by comparing the previous code, our tag system will be made up of two tags; each of them will contain a fragment:

<TabHost id=tabhost">
    <FrameLayout id="tabcontent">
        <FrameLayout id="tab1">
        </FrameLayout>
        <FrameLayout id="tab2">
        </FrameLayout>
    </FrameLayout>
    <TabWidget id="tabs" />
</TabHost>

With the previous code you can get an idea of what the general scheme of the tags in Android is like; As you can see, we simply have to follow an already defined pattern, now we need to establish each of the fragments in the tags from the activity:

TabHost tabs = (TabHost) findViewById(android.R.id.tabhost);
tabs.setup();

TabHost.TabSpec spec = tabs.newTabSpec("mitab1");
spec.setContent(R.id.tab1);
spec.setIndicator("TAB1");
tabs.addTab(spec);

spec = tabs.newTabSpec("mitab2");
spec.setContent(R.id.tab2);
spec.setIndicator("TAB2");
tabs.addTab(spec);

tabs.setCurrentTab(0);

if (savedInstanceState == NULL) {
   getSupportFragmentManager().beginTransaction()
           .add(R.id.tab1, new UnoFragment())
           .commit();

   getSupportFragmentManager().beginTransaction()
           .add(R.id.tab2, new DosFragment())
           .commit();
}

At this point, you will wonder why we created three fragments if we only used two, because if you have worked with an Android application that consumes services from another platform or that consists of different categories where one category is the parent or is at a higher level, this would lead us to replace the parent content by applying some selection which usually this fragment replacement would be through a gridview or listview but to keep our example simple we don't use any other grouped view.

In general what we want to do is replace fragment 2 with fragment 3 and vice versa; We can do it using the onclick event from the fragment 2/3 through a button using the following code:

DosFragment dosFragment = new DosFragment();
FragmentManager fragmentManager = myContext.getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.tab2, dosFragment).addToBackStack(NULL).commit();

As we can see, it is very simple, we replace it by the view identifier, which in our case is tab2, we can easily call this section of code from other related classes or grouped views such as gridview, listview or recyclerview.

Although as indicated at the beginning, it would not be entirely correct to place this type of logic in a fragment (fragments by definition must be independent of each other) for our practical case we used this solution.

You can find the full code in the Git repository at the beginning and end of this post.

Download

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.