Swipe views

In a previous post I implemented a layout with 2 tabs using an action bar and fragments; the disadvantage of this layout is that dragging horizzontally the views in a similar way to Google Play would be very natural for the user.
In Horizontal View Swiping with ViewPager you can see how to get this layout using ViewPager, which is part of the Compatibility Package.
I noticed that you get a similar code similar when you create a new Android project using Android SDK Tools Revision 20, and choosing as the Navigation Type in the project creation wizard “Swipe Views + Title Strip” as shown.

The code in this post is the same as that in Horizontal View Swiping with ViewPager but with the change that the layout of the fragments are taken from file .xml

  1. create an Android project
    • Build SDK: API 16
    • Minimum required SDK: API 14
    • don’t create activities
  2. import the Compatibility Package; maybe you already imported it if there is a directory “libs” with the file android-support-v4.jar, otherwise you do a right click on the project and select Android Tools -> Add Support Library or follow the instructions in Support Library
  3. edit the file AndroidManifest.xml
    <manifest xmlns:android=""
        <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="16" />
            android:theme="@style/AppTheme" >
                android:label="@string/app_name" >
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
  4. edit the file res/values/strings.xml
        <string name="app_name">Swipe Views</string>
        <string name="body1">one</string>
        <string name="body2">two</string>
        <string name="body3">three</string>
        <string name="label1">Tab 1</string>
        <string name="label2">Tab 2</string>
        <string name="label3">Tab 3</string>
  5. create the files main.xml, tab1.xml, tab2.xml e tab3.xml in the directory res/layout
    • main.xml
        Copyright 2012 The Android Open Source Project
        Licensed under the Apache License, Version 2.0 (the "License");
        you may not use this file except in compliance with the License.
        You may obtain a copy of the License at
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
      < xmlns:android=""
          This title strip will display the currently visible page title, as well as the page
          titles for adjacent pages.
          < android:id="@+id/pager_title_strip"
              android:paddingBottom="4dp" />
    • tab1.xml
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android=""
              android:text="@string/body1" />
    • tab2.xml
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android=""
              android:text="@string/body2" />
    • tab3.xml
      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android=""
              android:text="@string/body3" />

    the file main.xml consists of 2 parts: in the first part ( you define the ViewPager that contains the fragments of the tabs, in the second part ( you define the bar of the tabs setting its positions, colors and padding;
    the files tab*.xml contain the layout of the fragments

  6. create the file
     * Copyright 2012 The Android Open Source Project
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
    package eu.lucazanini.swipeviews;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    public class MainActivity extends FragmentActivity {
         * The {@link} that will provide
         * fragments representing each object in a collection. We use a
         * {@link} derivative,
         * which will destroy and re-create fragments as needed, saving and
         * restoring their state in the process. This is important to conserve
         * memory and is a best practice when allowing navigation between objects in
         * a potentially large collection.
        CollectionPagerAdapter mCollectionPagerAdapter;
         * The {@link} that will display the
         * object collection.
        ViewPager mViewPager;
        public void onCreate(Bundle savedInstanceState) {
    	// Create an adapter that when requested, will return a fragment
    	// representing an object in
    	// the collection.
    	// ViewPager and its adapters use support library fragments, so we must
    	// use
    	// getSupportFragmentManager.
    	mCollectionPagerAdapter = new CollectionPagerAdapter(
    	// Set up action bar.
    	final ActionBar actionBar = getActionBar();
    	// Specify that the Home button should show an "Up" caret, indicating
    	// that touching the
    	// button will take the user one step up in the application's hierarchy.
    	// Set up the ViewPager, attaching the adapter.
    	mViewPager = (ViewPager) findViewById(;
         * A {@link} that returns a
         * fragment representing an object in the collection.
        public class CollectionPagerAdapter extends FragmentStatePagerAdapter {
    	final int NUM_ITEMS = 3; // number of tabs
    	public CollectionPagerAdapter(FragmentManager fm) {
    	public Fragment getItem(int i) {
    	    Fragment fragment = new TabFragment();
    	    Bundle args = new Bundle();
    	    args.putInt(TabFragment.ARG_OBJECT, i);
    	    return fragment;
    	public int getCount() {
    	    return NUM_ITEMS;
    	public CharSequence getPageTitle(int position) {
    	    String tabLabel = null;
    	    switch (position) {
    	    case 0:
    		tabLabel = getString(R.string.label1);
    	    case 1:
    		tabLabel = getString(R.string.label2);
    	    case 2:
    		tabLabel = getString(R.string.label3);
    	    return tabLabel;
         * A dummy fragment representing a section of the app, but that simply
         * displays dummy text.
        public static class TabFragment extends Fragment {
    	public static final String ARG_OBJECT = "object";
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    		Bundle savedInstanceState) {
    	    Bundle args = getArguments();
    	    int position = args.getInt(ARG_OBJECT);
    	    int tabLayout = 0;
    	    switch (position) {
    	    case 0:
    		tabLayout = R.layout.tab1;
    	    case 1:
    		tabLayout = R.layout.tab2;
    	    case 2:
    		tabLayout = R.layout.tab3;
    	    View rootView = inflater.inflate(tabLayout, container, false);
    	    return rootView;

    the main class extends FragmentActivity and not Activity as usually;
    in the event onCreate you bind an instance of FragmentStatePagerAdapter (mCollectionPagerAdapter) to an instance of ViewPager (mViewPager) defined in the file main.xml;
    in the inner class CollectionPagerAdapter you define the number of the tabs (NUM_ITEMS) and override 3 methods: getItem in which you create the fragments, getCount that simply returns the number of the fragments (tabs) and getPageTitle that returns the labels of the tabs; in an other inner class TabFragment you create the fragments choosing the layout depending on the bundle passed to the fragment in the CollectionPagerAdapter;
    the class CollectionPagerAdapter is not static like in Horizontal View Swiping with ViewPager in order to get the string resources in the method getPageTitle, otherwise you need a static Context in the main class

  7. launch the app

25 replies on “Swipe views”

Ciao Luca seguito tutti i tuoi passaggi di questo tutorial, ma dopo aver lanciato l’applicazione sul mio telefono mi compare la notifica che l’applicazione si è fermata, in Android Studio non ci sono errori! da cosa può dipendere? La mia versione di Android è 4.4.2! Ho anche seguito la spiegazione sul sito di Android Studio l’applicazione viene eseguita ma non avendo i singoli tab nella cartella Layout non so come inserire i contenuti! Complimenti per i tuoi tutorial!

Ancora ciao, Vorrei inserire un bottone con un onClickActionListener, ad esempio in tab1. Come potrei fare? Ho dichiarato il bottone nel manifest ma nel codice java non so proprio dove inserirlo. Se provo mi crasha !

Intendi setOnClickListener?
Eventualmente qui trovi un esempio che forse riesci ad adattare.
Il pulsante non deve essere dichiarato in AndroidManifest.xml

Scusa, ho sbagliato a dire manifest; volevo dire nel layout xml 😀 . In ogni caso poi ho risolto.
Grazie ancora 🙂

Ciao, grazie per il tutorial. Come mai, nonostante il minimo SDK richiesto sia il 14, ovvero IceCream Sandwich, ci sono applicazioni simili anche per Android Gingerbread? Se provassi questo tutorial sulla mia versione, cioè 2.3.3, funzionerebbe?
Grazie ancora.

Credo di si, ma devi commentare le righe con actionBar nella classe MainActivity perchè la ActionBar è stata aggiunta con Android 3.0 (API level 11)

Grazie poi ho risolto. Utilizzando la libreria Sherlock si riesce a bypassare questo problema di compatibilità e, al posto di estendere FragmentActivity, si estende SherlockFragmentActivity che ha gli stessi metodi.

Ciao, sono nuovo della programmazione Android, sono nella stessa situazione proposta da te in questo commento (compatibilità con la 2.3.3), volevo chiedere come avere la libreria Sherlock, se si deve scaricare esternamente al sdk e come caricarla.

Ho risolto, ma in
final ActionBar actionBar = getSupportActionBar();
mi da l’errore “Type mismatch: cannot convert from to”,
come potrei risolvere??

Ciao Luca!avrei un dubbio. La mia app deve simulare una sorta di portafoglio all’interno del quale sono presenti diverse carte di credito. Nella mia schermata principale ho le prime 3 carte dell’utente. Se esegue lo swipe a destra vorrei vedere le altre carte (ovviamente se disponibili), sempre a 3 per view. Il mio problema è relativo al fatto che l’app è stata inizialmente progettata per un massimo di 3 carte, di conseguenza con un layout container con all’interno altri 3 layout(ognuno relativo ad una carta). Volendo ottenere ciò che ti ho descritto nelle righe precedenti, sarebbe possibile utilizzare la tua soluzione usando/ripetendo lo stesso layout(e quindi gli stessi id) per ogni view? O devo crearmi un layout con id diversi per ogni pagina?
Spero di essermi spiegato chiaramente. Se hai bisogno di altri dettagli chiedi pure. Ti ringrazio. Ciao!!!

Avendo lo stesso id, mi aspetto che anche il contenuto mostrato sia lo stesso, cioè stesso id stessa carta di credito.

In realtà no. Mi spiego meglio: ho modo di conoscere sin da subito il numero di carte totali che ha l’utente. La mia idea è che se mi trovo sulla view 1, mostro le carte con i dati relativi alle prime 3, se sono sulla view 2 mostro le carte(stessi id, ma dati diversi) con i dati delle carte dalla 4 alla 6, e cosi’ via..

Durante lo swipe si vedono contemporaneamente anche se parzialmente il layout corrente e quello successivo, se ci sono View con lo stesso id mi aspetto che mostrino lo stesso contenuto ma questo non è il comportamento voluto.
Quindi si dovrebbero usare più layout con id differenti; in alternativa è possibile usare il metodo setId della classe View per modificare l’id in runtime ma l’ho visto usato sempre in un contesto in cui tutto il layout era creato in runtime.

Ciao, ho seguito il procedimento ma non riesco a capire come far si che all’avvio dell’app venga mostrato un tab diverso dal primo. Come si fa?

Nella classe MainActivity alla fine del metodo onCreate aggiungi la riga


per selezionare la seconda tab all’avvio.

Ciao Luca,
ho eseguito il tuo tutorial e, funziona tutto alla perfezione, ora però mi trovo davanti ad un quesito.
Devo popolare le view dei fragment tramite valori presi da un db in maniera tale d’avere una sorta di catalogo che scorra con l’effetto swipe.
Come posso eseguire un’operazione del genere?

Grazie mille!

Con effetto swipe credo si intenda il passare da un layout all’altro orizzontalmente, ma forse tu intendi voler scorrere il catalogo in senso verticale, allora potresti fare una ricerca per ListFragment.

Thanks for this wonderful tutorial.
I would like to know the flow of this activity, like which method is called at what event. i tried putting debug points but could not configure the flow. please help me.

Thanks in advance

Nice! I use this setup for my new app. Now I want to implement some communication
betwenn the fragments. How is it possible to calculate a value in lets say fragment one
and communicate this to fragment two and use it for an ongoing calculation there?
Do you have some examples or tutorials or a general setup?
Bye Tom

You can use a variable member of the main activity.
Let me guess that the value you want to pass between the fragments is a String called myString with setter and getter methods.
You can access to myString in the fragments with the code:

  • MainActivity.getMyString();
    if myString and getter and setter methods are static
  • ((MainActivity)getActivity()).getMyString();
    if myString and getter and setter methods aren’t static

You can also use the setArguments and getArguments to pass a Bundle object; in the example of this post I use a bundle to pass the position of the tabs (an int value).

You are Incredible!!!

Thank you so much for taking the time to write this out!
I have tried a total of 6 other similar tutorials but none actually explained clearly how to break down each tab into an xml file for easy editing.
2 days searching until I came across this gem!
Thanks again!

Have a wonderful day! =)

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.