Autore Topic: [medio] Activity con ViewPager e Fragments  (Letto 20920 volte)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
[medio] Activity con ViewPager e Fragments
« il: 18 Marzo 2012, 11:06:42 CET »
+15
Livello di difficoltà : medio
Min SDK : 4
Sorgente : ZIP allegato e http://code.google.com/p/it-anddev-bradipao-mercury/


fonti:

Introduzione

Uno dei più comuni pattern di interfaccia utente è quello che consente di sfogliare le schermate come se fossero pagine, chiamato in gergo page swyping e ben noto a tutti perchè è la modalità di navigazione dell'Android Market (ora noto col nome Google Play).

Il support package (compatibility library) già visto nel tutorial sui Fragment mette a disposizione il ViewPager, una standardizzazione di questo pattern che supporta i fragment e che è compatibile sino ad android 1.6 (API 4). Ci sono diversi modi di implementare ed utilizzare il ViewPager, questo tutorial ne prende in considerazione uno dei più semplici.




Struttura del ViewPager

L'utilizzo dell'oggetto ViewPager ha molte analogie con le ListView, in quanto gestisce una sequenza di fragment proprio come la ListView gestisce una sequenza di view. Avremo infatti una lista di fragment, una adapter e l'oggetto ViewPager che ne gestisce la visualizzazione sfogliabile.

In modo del tutto analogo alle ListView, le fasi dell'utilizzo del ViewPager sono le seguenti:
  • Creo i fragment
  • Metto i fragment allocati all'interno di una lista
  • Creo un adapter (in questo caso è quello standard, ma può essere esteso a piacimento)
  • Associo all'adapter la lista dei fragment
  • Associo al ViewPager l'adapter

Nella nostra analogia c'è una differenza sostanziale. Quando cambiamo la base dati della ListView siamo soliti usare la notifyDatasetChange per far aggiornare la visualizzazione della lista. Nel nostro caso abbiamo una analoga notifyDatasetChange, ma NON serve per aggiornare il contenuto delle schermate. La prima volta questo aspetto può sorprendere, ma occorre ricordare che questa struttura con adapter serve a collegare i fragment e il ViewPager. La notifyDatasetChange serve a notificare al ViewPager che avete aggiunto o rimosso fragment dalla lista, non ad aggiornare il contenuto della schermata. Come vedremo, per l'aggiornamento vero e proprio delle schermate dovremo tenere conto di questo aspetto.

Altra cosa importante da sottolineare è che (nell'implementazione di questo tutorial) i fragment saranno istanziati all'avvio dell'activity e rimarranno sempre in memoria, approccio fattibile fintanto che il numero e la memoria occupata sono ragionevoli, altrimenti occorre passare ad implementazioni più complesse qua non mostrate. Se anche i fragment sono sempre allocati, le corrispondenti schermate (view) non lo sono. C'è un meccanismo di caching tale da tenere in memoria la schermata correntemente visualizzata e le due adiacenti su cui l'utente potrebbe "swipare". Come vedremo, in fase di aggiornamento delle schermate non visibili, questo comporta dover fare una distinzione tra schermata creata e non creata. 


Predisporsi all'utilizzo del ViewPager

Per poter usare i Fragment ed il ViewPager su Android pre-3.0 occorre includere nel progetto il Support Package ( Support Package | Android Developers ) e fare uso delle classi da esso fornite al posto di quelle native presenti solo da HoneyComb in poi.

  • Copiare il file android-support-v4.jar da %ANDROID-SDK%\extras\android\compatibility\v4 in un nuovo folder /libs sotto la root dell'applicazione
  • Cliccarci sopra col tasto destro, e selezionare add to build path per includerlo nella compilazione
  • Estendere le activity da FragmentActivity e non da Activity ( public class JanusActivity extends FragmentActivity )
  • Importare la classe Fragment dal support package e non quello nativo ( import android.support.v4.app.Fragment )


Contenuto del tutorial e layout

Nel nostro esempio avremo:
  • tre fragment da visualizzare in tre schermate consecutive: ciascun fragment avrà la propria gestione ed il proprio layout come di consueto
  • un button all'interno del primo fragment che cambia il testo visualizzato negli altri due: per mostrare modi e problematiche del passaggio dati tra le pagine (schermate)
  • una parte di layout non soggetta swiping contenente tre button per passare direttamente a ciascuna delle tre schermate: per mostrare come si gestisce la parte di layout che non si deve sfogliare e come eseguire programmaticamente il passaggio ad una delle pagine



Nel layout principale dell'activity è sufficiente dichiarare come al solito il layout e l'oggetto ViewPager che fornirà la vera e propria implementazione delle pagine sfogliabili.

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:gravity="center_horizontal"
   android:orientation="vertical"
   android:padding="4dip" >

    <LinearLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:gravity="center"
       android:orientation="horizontal" >

        <Button
           android:id="@+id/btnPag1"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="PAGE 1" >
        </Button>

        <Button
           android:id="@+id/btnPag2"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="PAGE 2" >
        </Button>

        <Button
           android:id="@+id/btnPag3"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="PAGE 3" >
        </Button>
    </LinearLayout>

    <android.support.v4.view.ViewPager
       android:id="@+id/pager"
       android:layout_width="match_parent"
       android:layout_height="0px"
       android:layout_weight="1" >
    </android.support.v4.view.ViewPager>

</LinearLayout>

Avremo poi i tre layout dei fragment, il primo col Button e gli altri con le TextView.

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#330000"
   android:gravity="center_horizontal|center_vertical"
   android:orientation="vertical" >

    <TextView
       android:id="@+id/tvText1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="PAGE 1"
       android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
       android:id="@+id/btWrite"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="WRITE to PAGES" >
    </Button>

</LinearLayout>

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#003300"
   android:gravity="center_horizontal|center_vertical"
   android:orientation="vertical" >

    <TextView
       android:id="@+id/tvText2"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="PAGE 2"
       android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="#000033"
   android:gravity="center_horizontal|center_vertical"
   android:orientation="vertical" >

    <TextView
       android:id="@+id/tvText3"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="PAGE 3"
       android:textAppearance="?android:attr/textAppearanceLarge" />

</LinearLayout>


Gestione del ViewPager

Come anticipato prima, nella OnCreate dell'activity creiamo i fragment, la lista che li contiene e l'adapter per il ViewPager.

Codice (Java): [Seleziona]
   // list contains fragments to instantiate in the viewpager
   List<Fragment> fragments = new Vector<Fragment>();
   // page adapter between fragment list and view pager
   private PagerAdapter mPagerAdapter;
   // view pager
   private ViewPager mPager;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
     
      // creating fragments and adding to list
      fragments.add(Fragment.instantiate(this,Page1Fragment.class.getName()));
      fragments.add(Fragment.instantiate(this,Page2Fragment.class.getName()));
      fragments.add(Fragment.instantiate(this,Page3Fragment.class.getName()));
     
      // creating adapter and linking to view pager
      this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(),fragments);
      mPager = (ViewPager) super.findViewById(R.id.pager);
      mPager.setAdapter(this.mPagerAdapter);

      // upper bar button listener, allows direct page access
      Button button = (Button)findViewById(R.id.btnPag1);
      button.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
            mPager.setCurrentItem(0);   // go to first page
         }
      });
      button = (Button)findViewById(R.id.btnPag2);
      button.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
            mPager.setCurrentItem(1);   // go to second page
         }
      });
      button = (Button)findViewById(R.id.btnPag3);
      button.setOnClickListener(new OnClickListener() {
         public void onClick(View v) {
            mPager.setCurrentItem(2);   // go to third page
         }
      });
   }

La classe PagerAdapter, estesa dalla FragmentPagerAdapter, in questo esempio è minimale. E' comunque lo scheletro di ciò che è necessario per implementazioni più complesse.

Codice (Java): [Seleziona]
public class PagerAdapter extends FragmentPagerAdapter {

   // fragments to instantiate in the viewpager
   private List<Fragment> fragments;
   
   // constructor
   public PagerAdapter(FragmentManager fm,List<Fragment> fragments) {
      super(fm);
      this.fragments = fragments;
   }
   
   // return access to fragment from position, required override
   @Override
   public Fragment getItem(int position) {
      return this.fragments.get(position);
   }

   // number of fragments in list, required override
   @Override
   public int getCount() {
      return this.fragments.size();
   }

}

Comunicare tra fragment

In modo del tutto analogo a quello presentato nel tutorial sui fragment, per comunicare eventi e dati si passa attraverso l'activity con un listener. Il fragment della prima pagina, quello contenente il button, dichiarerà una interfaccia con listener, così che al clic sul button l'evento viene trasferito all'activity padre. Nell'esempio sotto riportato, qualora l'activity padre non implementi il listener, nel viene istanziato uno locale (thanks to MarcoDuff).

Codice (Java): [Seleziona]
   // activity listener interface
   private OnPageListener pageListener;
   public interface OnPageListener {
      public void onPage1(String s);
   }
   
   // onAttach : set activity listener
   @Override
   public void onAttach(Activity activity) {
      super.onAttach(activity);
      // if implemented by activity, set listener
      if(activity instanceof OnPageListener) {
         pageListener = (OnPageListener) activity;
      }
      // else create local listener (code never executed in this example)
      else pageListener = new OnPageListener() {
         @Override
         public void onPage1(String s) {
            Log.d("PAG1","Button event from page 1 : "+s);
         }
      };
   }
   
   // onCreateView :
   @Override
   public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
     
      // fragment not when container null
      if (container == null) {
         return null;
      }
      // inflate view from layout
      View view = (LinearLayout)inflater.inflate(R.layout.page1,container,false);
      // get button reference
      btnWrite = (Button) view.findViewById(R.id.btWrite);
      // set button listener to trigger activity listener
      btnWrite.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            pageListener.onPage1("Page 1 to");
         }
      });
      // update text
      TextView tv = (TextView) view.findViewById(R.id.tvText1);
      tv.setText(ptext);
     
      return view;
   }

I fragment con le textview hanno una funzione membro che permette di scrivere nella textview stessa

Codice (Java): [Seleziona]
public class Page2Fragment extends Fragment {

   Button btnWrite;
   public String ptext="..PAGE 2..";
   
   public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
     
      // fragment not when container null
      if (container == null) {
         return null;
      }
      // inflate view from layout
      View view = (LinearLayout)inflater.inflate(R.layout.page2,container,false);
      // update text
      TextView tv = (TextView) view.findViewById(R.id.tvText2);
      tv.setText(ptext);
     
      return view;
   }
   
   // set text helper function
   public void setText(String item) {
      TextView view = (TextView) getView().findViewById(R.id.tvText2);
      view.setText(item);
   }
   
}

L'activity implementa il listener, che si occupa di aggiornare le textview degli altri fragment

Codice (Java): [Seleziona]
   // page 1 fragment listener implementation
   @Override
   public void onPage1(String s) {    
     
      // set activity data with received string
      p2text = new String(s+" 2");
      p3text = new String(s+" 3");

      // page 2 fragment update
      Page2Fragment f2 = (Page2Fragment) fragments.get(1);
      f2.ptext = p2text;
      // if page 2 view is already created, update
      View v2 = f2.getView();
      if (v2!=null) {
         f2.setText(p2text+" direct");
      }
     
      // page 3 fragment update
      Page3Fragment f3 = (Page3Fragment) fragments.get(2);
      f3.ptext = p3text;
      // if page 3 view is already created, update
      View v3 = f3.getView();
      if (v3!=null) {
         f3.setText(p3text+" direct");
      }
     
   }

In quest'ultima parte di codice si può notare la peculiarità che si era accennata all'inizio:
  • Per aggiornare la pagina adiacente, occorre aggiornare sia la base dati del fragment che la sua view, perchè esiste già (notare l'if) e passando a tale pagina non verrebbe automaticamente rigenerata.
  • Per aggiornare la pagina 3, non adiacente, basta aggiornare la base dati, perchè la rispettiva view non esiste ancora.

NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:[medio] Activity con ViewPager e Fragments
« Risposta #1 il: 18 Marzo 2012, 11:46:16 CET »
0
Grazie bradipao, molto interessante!!

Offline ignaz

  • Utente junior
  • **
  • Post: 54
  • Respect: +2
    • Mostra profilo
  • Dispositivo Android:
    Galaxy s2
  • Sistema operativo:
    Win 7 64bit
Re:[medio] Activity con ViewPager e Fragments
« Risposta #2 il: 03 Aprile 2012, 18:28:57 CEST »
0
Ho scaricato l'allegato, ma poi non si riesce ad importarlo su eclipse!
Sbaglio qualche cosa?

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Activity con ViewPager e Fragments
« Risposta #3 il: 03 Aprile 2012, 21:01:16 CEST »
0
Sinceramente non ho provato a reimportare lo ZIP.

Dato che il progetto è veramente minimale, ci metti poco a crearne uno nuovo e copiare i file nei folder.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline ignaz

  • Utente junior
  • **
  • Post: 54
  • Respect: +2
    • Mostra profilo
  • Dispositivo Android:
    Galaxy s2
  • Sistema operativo:
    Win 7 64bit
Re:[medio] Activity con ViewPager e Fragments
« Risposta #4 il: 03 Aprile 2012, 23:58:46 CEST »
0
Ciao ho creato la mia app come il tutorial, ringrazio  l'autore che è stato chiarissimo,  ma ho un problema se metto più di un fragment mi viene sempre generata una eccezione quando l'activity principale passa dallo stato attivo a pausa. lo fa quando cambio orientamento o quando apro un'altra activity.

Se aggiungo un solo fragment è perfetta, ma quando ne metto due l'applicazione funziona correttamente anche passando da un fragment all'altro ma da il problema sopra descritto e crasha.
il logcat dell'errorre è sotto:
Ho capito che è un null ma non riesco a capire dove ...  chi mi aiuta ??


 04-03 16:26:07.708: E/AndroidRuntime(859): FATAL EXCEPTION: main
04-03 16:26:07.708: E/AndroidRuntime(859): java.lang.RuntimeException: Unable to pause activity {it.bolognini.CVA/it.bolognini.CVA.ViewPagerFragmentActivity}: java.lang.NullPointerException
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2354)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2311)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2803)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread.access$1600(ActivityThread.java:117)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.os.Looper.loop(Looper.java:123)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread.main(ActivityThread.java:3683)
04-03 16:26:07.708: E/AndroidRuntime(859):    at java.lang.reflect.Method.invokeNative(Native Method)
04-03 16:26:07.708: E/AndroidRuntime(859):    at java.lang.reflect.Method.invoke(Method.java:507)
04-03 16:26:07.708: E/AndroidRuntime(859):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
04-03 16:26:07.708: E/AndroidRuntime(859):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
04-03 16:26:07.708: E/AndroidRuntime(859):    at dalvik.system.NativeStart.main(Native Method)
04-03 16:26:07.708: E/AndroidRuntime(859): Caused by: java.lang.NullPointerException
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1576)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1617)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:481)
04-03 16:26:07.708: E/AndroidRuntime(859):    at it.bolognini.CVA.ViewPagerFragmentActivity.onSaveInstanceState(ViewPagerFragmentActivity.java:173)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.Activity.performSaveInstanceState(Activity.java:1037)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1181)
04-03 16:26:07.708: E/AndroidRuntime(859):    at android.app.ActivityThread.performPauseActivity(ActivityThread.java:2336)
04-03 16:26:07.708: E/AndroidRuntime(859):    ... 12 mor

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Activity con ViewPager e Fragments
« Risposta #5 il: 04 Aprile 2012, 08:10:32 CEST »
0
Lo fa anche nel progetto originario o stai provando sul tuo? In quest'ultimo caso puoi postare il codice di ViewPagerFragmentActivity ed indicare qual'è la riga 173?
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline ignaz

  • Utente junior
  • **
  • Post: 54
  • Respect: +2
    • Mostra profilo
  • Dispositivo Android:
    Galaxy s2
  • Sistema operativo:
    Win 7 64bit
Re:[medio] Activity con ViewPager e Fragments
« Risposta #6 il: 04 Aprile 2012, 11:38:02 CEST »
0
Ciao Grazie per l'interessamento, lo fa anche con il progetto originale che ho rimontato io quindi potrei aver commesso qualche errore.
Alla riga 173  non c'è codice mio è quella riportata sotto:  super.on...  avevo fatto l'override per vedere a che punto andava in errore.
     
     @Override
   public void onSaveInstanceState(Bundle savedInstanceState) {
       super.onSaveInstanceState(savedInstanceState);
       // your stuff or nothing
   }

Sviluppo in java da poco sono pratico di c# e non ho ancora ben chiaro lo stacktrace
Ho controllato la savedInstanceState ed non è nullo

Offline ignaz

  • Utente junior
  • **
  • Post: 54
  • Respect: +2
    • Mostra profilo
  • Dispositivo Android:
    Galaxy s2
  • Sistema operativo:
    Win 7 64bit
Re:[medio] Activity con ViewPager e Fragments
« Risposta #7 il: 04 Aprile 2012, 17:32:09 CEST »
+2
AGGIORNAMENTO girando un po in rete ho scoperto che è un bug noto
"Your problem is related to a bug in FragmentManager::saveFragmentBasicState. The bug (and a workaround at the bottom) are reported in an issue report here."
http://stackoverflow.com/questions/8748064/starting-activity-from-fragment-causes-nullpointerexception/9446326#9446326
La soluzione veloce che sembra funzionare è inserire nel Fragment questo codice
Codice (Java): [Seleziona]
 
   @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        setUserVisibleHint(true);
    }

Altre info qui : http://code.google.com/p/android/issues/detail?id=19211

Spero possa essere utili a qualcuno.

Offline stranigiorni

  • Nuovo arrivato
  • *
  • Post: 20
  • Respect: 0
    • Google+
    • matteogabella
    • Mostra profilo
    • stranigiorni
  • Dispositivo Android:
    bird v1277
  • Play Store ID:
    Matteo+Gabella
  • Sistema operativo:
    win8
Re:[medio] Activity con ViewPager e Fragments
« Risposta #8 il: 10 Aprile 2012, 18:40:01 CEST »
0
grazie mille bradipao, mi hai aperto un mondo...
come quando mangi un melograno e trovi una nuova sezione...
 ;-)

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:[medio] Activity con ViewPager e Fragments
« Risposta #9 il: 10 Aprile 2012, 18:58:53 CEST »
0
...
Spero possa essere utili a qualcuno.

Ignaz, ti ringrazio molto per aver indagato e riportato la possibile soluzione (ce ne fossero utenti così  :-) ). Purtroppo in queste settimane, ed ancora per altre due, ho scadenze molto pressanti a lavoro che mi impediscono di dedicarmi al divertimento, e non avrei potuto fare prove ancora per un po'.

Stranigiorni, forse non ci crederai, ma fa piacere sapere di aver fatto qualcosa di utile.  :-P
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline dadino

  • Nuovo arrivato
  • *
  • Post: 3
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg Optimus 2x
  • Sistema operativo:
    Windows 7
Re:[medio] Activity con ViewPager e Fragments
« Risposta #10 il: 14 Maggio 2012, 23:52:35 CEST »
0
Sto usando questo tutorial per avere un fragment con dei pulsanti a sinistra e un listfragment che è praticamente il log di quello che succede a sinistra.
Ho un problema enorme però. Usando il getActivity() non mi trova i metodi che io scrivo nell'activity principale (ad esempio uno con cui aggiorno una list che ho nella activity principale). Il messaggio di Eclipse è The method "nome del mio metodo" is undefined for the type FragmentActivity. E' come se non riconoscesse la activity padre come, appunto, padre.

Edit: mi ero dimenticato di scrivere che per ovviare avevo messo i metodi e le variabili dell'activity da chiamare STATIC e li chiamo usando nomeActivity.nomeMetodo() o nomeActivity.nomeVariabile()
Per ora sono riuscito a far funzionare l'app, ma non comprendo a pieno le conseguenze di mettere questi metodi e variabili come static!
(ottimo tutorial, l'app funziona con lo swype, hai qualche idea per aggiungere i nomi dei fragments in alto, tipo sui feed dell'app di google+)
« Ultima modifica: 15 Maggio 2012, 01:25:41 CEST da dadino »

Offline DarnellNajanReed

  • Utente normale
  • ***
  • Post: 359
  • Respect: +49
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus One, Acer Iconia A500/501, Asus Transformer Prime, Galaxy ACE, Galaxy S Plus, Galaxy S Advance P, Galaxy Tab 2 7.0, Google Nexus 7
  • Play Store ID:
    Luigi Notaro
  • Sistema operativo:
    OS X 10.8.3
Re:[medio] Activity con ViewPager e Fragments
« Risposta #11 il: 15 Maggio 2012, 10:18:59 CEST »
+1
Se il getActivity() ti ritorna il riferimento ad una FragmentActivity, ovviamente questo non può conoscere i metodi implementati da una classe che da lei eredita.

Eviterei di mettere quei metodi come static...piuttosto puoi dare al Fragment un riferimento ad una interfaccia che implementa la tua FragmentActivity, la quale appunto mette a contratto quali metodi questa deve implementare per poter ospitare quel Fragment.

Metodo sporco (e venuto su al momento, potrebbe essere una gran boiata): prova a castare il ritorno getActivity al tipo "MiaFragmentActivity".

Offline dadino

  • Nuovo arrivato
  • *
  • Post: 3
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg Optimus 2x
  • Sistema operativo:
    Windows 7
Re:[medio] Activity con ViewPager e Fragments
« Risposta #12 il: 15 Maggio 2012, 12:03:23 CEST »
0
E' esattamente quello che avevo capito dall'errore, il fragment non capisce in che activity si trova e quindi non può usarne i metodi. Come faccio a fargli capire in che activity si trova dunque (credo di aver capito cosa mi hai consigliato, ma non lo so riportare in codice)?


EDIT: Perchè sconsigli di usare metodi static?

Offline Melanogaster

  • Utente normale
  • ***
  • Post: 260
  • Respect: +11
    • Mostra profilo
  • Dispositivo Android:
    SII
  • Sistema operativo:
    Kubuntu
Re:[medio] Activity con ViewPager e Fragments
« Risposta #13 il: 04 Luglio 2012, 15:41:55 CEST »
0
Avrei una domanda:
quel che vorrei fare e' realizzare un'activity multi-fragment (intercambiabili con swype), e fin qui ci sono...
Ne riesco a creare quante ne voglio.
Il problema e' che questi fragment sono tutti generati dalla stessa classe.
Praticamente vorrei creare due fragment: uno con la lista della Frutta ed uno con la lista dei Dolci, pero' entrambi si basano sulla stessa classe, ma devono restituire dati diversi prelevati dal database.
Come potrei fare per personalizzare ogni fragment a seconda della corrispondenza? (fragment in prima posizione, preleva i record con id = 1, fragment in seconda posiziona preleva i record con id = 2)

Grazie :)

Offline iceweasel

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 878
  • Respect: +147
    • Mostra profilo
  • Dispositivo Android:
    LGE P990 - Google Nexus 5
  • Sistema operativo:
    Linux Debian Sid
Re:[medio] Activity con ViewPager e Fragments
« Risposta #14 il: 04 Luglio 2012, 23:52:07 CEST »
+2
La classe Fragment ha il metodo setArguments per impostare gli argomenti per personalizzare l'oggetto una volta instanziato ma non ancora utilizzato.  Basta poi nel onCreate, ad esempio, chiamare il metodo getArguments per leggere gli argomenti e comportarsi di conseguenza.
adb logcat | tee /tmp/logcat | grep TAG