2012-04-10 4 views
17

Ho provato così tanto a ottenere actionbarsherlock + tabs + frammenti funzionanti.Actionbarsherlock + schede + multi frammenti?

Posso solo rendere questo set funzionante come statico, vorrei creare questo come app Android Market (movimento a scorrimento).

Mi blocco quando è necessario gonfiare un layout con più frammenti all'interno.

In Support4demos, ho ottenuto FragmentsTabsPager come esempio da seguire.

+0

È necessario pubblicare il codice con cui si verificano problemi e LogCat se vengono generate eccezioni. Se vuoi scorrere tra 'Fragments' devi usare' ViewPager'. – adneal

+0

https://github.com/JakeWharton/ActionBarSherlock/blob/master/samples/fragments/src/com/actionbarsherlock/sample/fragments/FragmentTabsPager.java –

risposta

10

Hai bisogno delle librerie giuste per implementare ciò che desideri.

Fondamentalmente, una libreria ViewPager è ciò che manca a voi. I miei suggerimenti:

1. ActionBarSherlock

È così morto facile da lavorare che non voglio spiegare.

2. ViewPagerExtensions

lo si può trovare here. Scarica i file ZIP e crea un nuovo progetto da esso.

Posso solo rendere questo set funzionante come statico, vorrei creare questo come app Android Market (movimento swype).

Implementare com.astuetz.viewpager.extensions.SwipeyTabsView da questo progetto. Ci sono esempi facili da seguire. fa esattamente quello che vuoi. Esistono anche altri stili di tabulazione tra cui scegliere (inclusa la nuova scheda Persone fornita con ICS). Inoltre, è molto facile adattarlo alla tua identità dell'app.

3. FragmentPagerAdapter

Infine, quella classe dalla libreria di supporto (v4).

Buona fortuna, e sii libero di chiedermi se hai bisogno di più aiuto.


Non è necessario eseguire l'override instantiateItem in FragmentPagerAdapter se si sta utilizzando quello che ho suggerito. Hai solo bisogno di

  1. Fornire un costruttore con un FragmentManager e chiamare la super implementazione;
  2. Override getCount restituire il numero di frammenti in vostro cercapersone, e
  3. getItem, che è quello che verrà utilizzato per restituire i frammenti per la creazione.

Questo è un esempio del codice che ho qui (un esempio di produzione completo e funzionante). Si tratta di una classe interna per l'attività che implementa il cercapersone:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter { 

    public MyFragmentPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    @Override 
    public int getCount() { 
     return 2; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     Fragment f; 
     switch(position) { 
     case 0: 
      f= new ItemSalesDataFragment(); 
      break; 
     case 1: 
      f= new DepartmentChooserFragment(); 
      break; 
     default: 
      throw new IllegalArgumentException("not this many fragments: " + position); 
     } 
     return f; 
    } 
} 

Come si può vedere, questo cercapersone gestisce due 'pagine', i display di sinistra dati di vendita.Quello giusto consente all'utente di selezionare quale dipartimento. Questi vengono restituiti nel metodo getItem. I frammenti corretti (puoi usare qualunque frammento hai già, nessuna modifica necessaria).

Come previsto, si entra in tutto questo insieme da 1) la creazione di un oggetto che un'istanza MyFragmentPagerAdapter, e 2) impostando l'adattatore al ViewPager oggetto da quella classe che appena un'istanza. Come puoi vedere, il suo metodo getItem "darà" al cercapersone tutti i frammenti di cui hai bisogno. Esempio:

mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager()); 
mViewPager.setAdapter(mFragmentPagerAdapter); 

Naturalmente, ci sono altre cose, di creare i pulsanti della scheda stessi e unire tutto questo incrociata comunicare. Suggerisco di guardare gli esempi forniti nel file ZIP di ViewPagerExtensions scaricato da GitHub. Questa è solo la risposta alla domanda nel tuo commento. Come puoi vedere, non è tanto il codice che usa questa libreria.

+0

Raccomando la libreria ViewPagerExtensions perché mi è piaciuto il codice generato e anche perché fornisce diversi tipi di schede tra cui è possibile scegliere, oltre ad essere molto facili da personalizzare. Se trovi l'approccio di Rymnel limitato in quello che puoi fare, assicurati di provarlo. – davidcesarino

+0

grazie, aiuta davvero. Ora ho bisogno di imparare come gonfiare due layout per ogni posizione all'interno: Object instantiateItem (Visualizza contenitore, posizione int), hai qualche tutorial? grazie – Marckaraujo

+0

Risposta aggiornata per mostrare un esempio di come si usa 'FragmentpagerAdapter' per restituire i frammenti necessari. Se hai bisogno di altri aiuti, sii libero di chiedere. – davidcesarino

38

In realtà sono riuscito a farlo funzionare senza nulla più della libreria ABS e della libreria di supporto. Ecco il mio codice:

public class ActionBarTabs extends SherlockFragmentActivity { 
CustomViewPager mViewPager; 
TabsAdapter mTabsAdapter; 
TextView tabCenter; 
TextView tabText; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

    mViewPager = new CustomViewPager(this); 
    mViewPager.setId(R.id.pager); 

    setContentView(mViewPager); 
    ActionBar bar = getSupportActionBar(); 
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
    bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 

    mTabsAdapter = new TabsAdapter(this, mViewPager); 

    mTabsAdapter.addTab(bar.newTab().setText("Home"), 
      ToolKitFragment.class, null); 
    mTabsAdapter.addTab(bar.newTab().setText("FujiSan"), 
      FujiFragment.class, null); 
} 

public static class TabsAdapter extends FragmentPagerAdapter implements 
     ActionBar.TabListener, ViewPager.OnPageChangeListener { 
    private final Context mContext; 
    private final ActionBar mActionBar; 
    private final ViewPager mViewPager; 
    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

    static final class TabInfo { 
     private final Class<?> clss; 
     private final Bundle args; 

     TabInfo(Class<?> _class, Bundle _args) { 
      clss = _class; 
      args = _args; 
     } 
    } 

    public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) { 
     super(activity.getSupportFragmentManager()); 
     mContext = activity; 
     mActionBar = activity.getSupportActionBar(); 
     mViewPager = pager; 
     mViewPager.setAdapter(this); 
     mViewPager.setOnPageChangeListener(this); 
    } 

    public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { 
     TabInfo info = new TabInfo(clss, args); 
     tab.setTag(info); 
     tab.setTabListener(this); 
     mTabs.add(info); 
     mActionBar.addTab(tab); 
     notifyDataSetChanged(); 
    } 

    @Override 
    public int getCount() { 
     return mTabs.size(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     TabInfo info = mTabs.get(position); 
     return Fragment.instantiate(mContext, info.clss.getName(), 
       info.args); 
    } 

    @Override 
    public void onPageScrolled(int position, float positionOffset, 
      int positionOffsetPixels) { 
    } 

    @Override 
    public void onPageSelected(int position) { 
     mActionBar.setSelectedNavigationItem(position); 
    } 

    @Override 
    public void onPageScrollStateChanged(int state) { 
    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     Object tag = tab.getTag(); 
     for (int i = 0; i < mTabs.size(); i++) { 
      if (mTabs.get(i) == tag) { 
       mViewPager.setCurrentItem(i); 
      } 
     } 
    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
    } 

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

Si carica il contenuto della scheda in base a quanto segue.

mTabsAdapter.addTab(bar.newTab().setText("Home"), 
      YOURFRAGMENTHERE.class, null); 

Questo vi darà la bella effetto "scheda swipey", come si fa riferimento ad esso, con ABS, la libreria di supporto e frammenti. ABS rende davvero questo quasi come lavorare con le librerie native. Ho effettivamente copiato questo codice direttamente dall'esempio di schede di paging di Google e l'ho modificato leggermente per l'ABS.

Spero che questo aiuti!

+1

Beh, lo capisco, ma il mio problema è la classe dei frammenti, è sempre in crash, potresti per favore condividere o darmi un modo come creare questa classe di frammenti con 2 o più frammenti all'interno? grazie – Marckaraujo

+0

Incredibile. Grazie. Molto meglio degli esempi forniti con ABS perché questo dà frammenti con le nuove e adorabili schede ICS in contrasto con l'esempio ABS che sembra tornare alle vecchie schede quando si usano i frammenti –

+2

Grazie per il codice di esempio, questo è esattamente quello che ero cercando! C'è una cosa anche se non sembra capire, a cosa serve "CustomViewPager"? Sembra funzionare bene anche con il ViewPager predefinito. – Glenn85

3

Un sacco di esempi di solito generano un'eccezione (IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first) quando si passa a una scheda precedentemente selezionata.

Mi piace adattare l'esempio di Google con un anziché un semplice FragmentPageAdapter, che sostituirà i frammenti e risolverà questo errore. Normalmente questo distruggerà i frammenti che può essere rimosso per risparmiare spazio; sostituisci destroyItem(ViewGroup, int, Object) con un blocco vuoto se vuoi tenere sempre i tuoi frammenti.

Ecco un esempio:

public class ActionBarTabs extends SherlockFragmentActivity { 
    CustomViewPager mViewPager; 
    TabsAdapter mTabsAdapter; 
    TextView tabCenter; 
    TextView tabText; 
    ActionBar mActionBar; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
      WindowManager.LayoutParams.FLAG_FULLSCREEN); 

     mViewPager = new CustomViewPager(this); 
     mViewPager.setId(R.id.pager); 

     setContentView(mViewPager); 
     mActionBar = getSupportActionBar(); 
     mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     mActionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE); 

     mTabsAdapter = new TabsAdapter(this, mViewPager); 

     mTabsAdapter.addTab(mActionBar.newTab().setText("Page 1"), 
      YOURFRAGMENT_A.class, null); 
     mTabsAdapter.addTab(mActionBar.newTab().setText("Page 2"), 
      YOURFRAGMENT_B.class, null); 
     mTabsAdapter.addTab(mActionBar.newTab().setText("Page 3"), 
      YOURFRAGMENT_C.class, null); 
    } 

    public static class TabsAdapter extends FragmentPagerAdapter 
      implements ActionBar.TabListener, ViewPager.OnPageChangeListener { 
     private final Context mContext; 
     private final ActionBar mActionBar; 
     private final ViewPager mViewPager; 
     private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>(); 

     static final class TabInfo { 
      private final Class<?> clss; 
      private final Bundle args; 

      TabInfo(Class<?> _class, Bundle _args) { 
       clss = _class; 
       args = _args; 
      } 
     } 

     public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) { 
      super(activity.getSupportFragmentManager()); 
      mContext = activity; 
      mActionBar = activity.getSupportActionBar(); 
      mViewPager = pager; 
      mViewPager.setAdapter(this); 
      mViewPager.setOnPageChangeListener(this); 
     } 

     public void addTab(ActionBar.Tab tab, Class<?> clss, Bundle args) { 
      TabInfo info = new TabInfo(clss, args); 
      tab.setTag(info); 
      tab.setTabListener(this); 
      mTabs.add(info); 
      mActionBar.addTab(tab); 
      notifyDataSetChanged(); 
     } 

     @Override 
     public int getCount() { 
      return mTabs.size(); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      TabInfo info = mTabs.get(position); 
      return Fragment.instantiate(mContext, 
       info.clss.getName(), info.args); 
     } 

     @Override 
     public void onPageScrolled(int position, float positionOffset, 
      int positionOffsetPixels) { 
     } 

     @Override 
     public void onPageSelected(int position) { 
      mActionBar.setSelectedNavigationItem(position); 
     } 

     @Override 
     public void onPageScrollStateChanged(int state) { 
     } 

     @Override 
     public void onTabSelected(Tab tab, FragmentTransaction ft) { 
      Object tag = tab.getTag(); 
      for (int i = 0; i < mTabs.size(); i++) { 
       if (mTabs.get(i) == tag) { 
        mViewPager.setCurrentItem(i); 
       } 
      } 
     } 

     @Override 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     } 

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

funziona bene con ABS ed è relativamente semplice da implementare.