Home / Programmazione / Java Android / Usare i Tab e i Fragment in Android
Mattepuffo

Usare i Tab e i Fragment in Android

Usare i Tab e i Fragment in Android

Nelle ultime versioni delle API, Google ci ha messo a disposizione i layout a tab, cosa che semplifica di molto la creazione di un layout, appunto, con i tab (che prima si doveva fare a mano).

Vediamo come usare questo tipo di layout con i Fragment.

Cominciamo con il layout che imposteremo nella Activity:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".BancaActivity"
    tools:ignore="MergeRootFrame" >

    <fragment
        android:id="@+id/entries_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginTop="?android:attr/actionBarSize"
        class="com.mp.banca.EntriesFragment" >
    </fragment>

    <fragment
        android:id="@+id/releases_fragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_marginTop="?android:attr/actionBarSize"
        class="com.mp.banca.ReleasesFragment" >
    </fragment>

</FrameLayout>

Come vedete ci sono due elementi Fragment, che puntano a due specifiche classi.

L'activity in questione sarà una cosa del genere:

public class BancaActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_banca);
        final ActionBar actionBar = getActionBar();
        actionBar.addTab(actionBar.newTab().setText(R.string.tab_last_entries).setTabListener(new MyTabListener<EntriesFragment>(this, "entries", EntriesFragment.class)));
        actionBar.addTab(actionBar.newTab().setText(R.string.tab_last_releases).setTabListener(new MyTabListener<ReleasesFragment>(this, "entries", ReleasesFragment.class)));
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater m = getMenuInflater();
        m.inflate(R.menu.general_menu, menu);
        return true;
    }

    public static class MyTabListener<T extends Fragment> implements TabListener {
        private Fragment fragment;
        private final Activity activity;
        private final String tag;
        private final Class<T> cls;

        public MyTabListener(Activity activity, String tag, Class<T> cls) {
            this.activity = activity;
            this.tag = tag;
            this.cls = cls;
        }

        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            if (fragment == null) {
                fragment = Fragment.instantiate(activity, cls.getName());
                ft.add(android.R.id.content, fragment, tag);
            } else {
                ft.replace(android.R.id.content, fragment);
            }
        }

        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            ft.remove(fragment);
        }

        public void onTabReselected(Tab tab, FragmentTransaction ft) {
        }
    }

}

Nel mio caso ho solo due tab, e ad ogni Tab corrisponde un Fragment.

La classe statica MyTabListener ci permette di richiamare il Fragment giusto quando di clicca su un tab.

Il costruttore della classe richiede tre parametri; nell'ultimo gli passiamo la classe che rappresenta il nostro Fragment.

Importante quello che avviene nel metodo onTabSelected, in quanto controlliamo se un Fragment è già stato creato, e in base a ciò lo aggiungiamo o lo "rimpiazziamo".

Nel metodo onTabUnselected invece lo rimoviamo.

Con queste due operazioni siamo sicuri che i Fragment non si sovrappongano.

A questo punto vediamo un Fragment di esempio:

public class EntriesFragment extends Fragment {
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.layout_fragment, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

}

Nel metodo onCreate impostiamo un layout, che dobbiamo creare come ci serve a noi a seconda di quello che ci dobbiamo fare (in un prossimo tutorial vedremo come integrare una ListView).

Nel metodo onActivityCreated svolgiamo altre operazioni (connessioni asincrone, ecc).