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
  4. edit the file res/values/strings.xml
  5. create the files main.xml, tab1.xml, tab2.xml e tab3.xml in the directory res/layout
    • main.xml
    • tab1.xml
    • tab2.xml
    • tab3.xml

    the file main.xml consists of 2 parts: in the first part (android.support.v4.view.ViewPager) you define the ViewPager that contains the fragments of the tabs, in the second part (android.support.v4.view.PagerTitleStrip) 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 eu.lucazanini.viewpager.MainActivity.java

    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 to “Swipe views”

  1. 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!

  2. 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 !

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

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

  3. 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.

    1. 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)

      1. 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.

        1. 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.

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

  4. 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!!!

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

      1. 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..

        1. 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.

  5. 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?

    1. Nella classe MainActivity alla fine del metodo onCreate aggiungi la riga

      per selezionare la seconda tab all’avvio.

  6. 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!

    1. 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.

  7. 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

  8. 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

    1. 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();
        MainActivity.setMyString(…);
        if myString and getter and setter methods are static
      • ((MainActivity)getActivity()).getMyString();
        ((MainActivity)getActivity()).setMyString(…);
        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).

  9. 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. Required fields are marked *

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