2015-04-12 15 views
5

Ho un'attività che comprende tre frammenti. I frammenti usano le schede della barra delle azioni usando un PagerAdapter. Quello che voglio fare è accedere a un metodo nel frammento a schede attivo dall'attività principale. Ho provato il codice qui sotto, ma questo restituisce il frammento come null, quindi immagino che non riesca a trovarlo all'interno delle schede!Chiamata metodo frammento a schede da Attività

NPListFragment articleFrag = (NPListFragment) getSupportFragmentManager().findFragmentByTag("NP"); 
    articleFrag.refreshT(); 

PagerAdapter:

public class AppSectionsPagerAdapter extends FragmentPagerAdapter { 
public AppSectionsPagerAdapter(FragmentManager fm) { 
    super(fm); 
} 

@Override 
public Fragment getItem(int i) { 
    switch (i) { 
     case 0: 
      return new NPListFragment(); 
     case 1: 
      return new PListFragment(); 
     case 2: 
      return new FavouritesFragment(); 
    } 
    return null; 
} 

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

} Può chiunque raccomandare? Ho dedicato circa 6 ore a questo, non sto facendo progressi per risolvere questo problema.

+0

Potete mostrare il vostro PagerAdapter? –

+0

aggiunto adattatore per cercapersone - grazie – user2029541

risposta

13

Cosa si deve fare: creare solo una volta ciascun frammento e quindi assegnarlo per tutte le chiamate al metodo getItem.

Per esempio:

public class AppSectionsPagerAdapter extends FragmentPagerAdapter { 

Fragment one, two, three; 

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

@Override 
public Fragment getItem(int i) { 
    switch (i) { 
     case 0: 
      if(one == null) 
       one = new NPListFragment(); 
      return one; 
     case 1: 
      if(two == null) 
       two= new PListFragment(); 
      return two; 
     case 2: 
      if(three == null) 
       three= new FavouritesFragment(); 
      return three; 
    } 
    return null; 
} 

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

} 

Ora, è anche nella vostra attività è possibile chiamare getItem

Avrete solo bisogno di lanciare alla vera classe frammento se si desidera chiamare un metodo specifico .

int pos = viewpager.getCurrentItem();  
Fragment activeFragment = adapter.getItem(pos); 
if(pos == 0) 
    ((NPListFragment)activeFragment).refreshT(); 
... 
+0

bella soluzione, ma sto ricevendo eccezione puntatore nullo di visualizzazioni quando ho provato ad accedervi in ​​frammento. Questo sta accadendo solo dopo aver ripristinato l'adattatore tra l'accesso alle viste. Qualche idea? – VinKrish

+1

Questo creerà un altro frammento vuoto e le loro viste saranno nulle. È necessario registrare i frammenti creati in precedenza e accedervi con un metodo getter. –

2

È necessario registrare i frammenti durante la compilazione, quindi accedervi dall'esterno.

public class AppSectionsPagerAdapter extends FragmentPagerAdapter { 
private SparseArray<Fragment> registeredFragments = new SparseArray<>(); 
public AppSectionsPagerAdapter(FragmentManager fm) { 
    super(fm); 
} 

@Override 
public Fragment getItem(int i) { 
    switch (i) { 
     case 0: 
      return new NPListFragment(); 
     case 1: 
      return new PListFragment(); 
     case 2: 
      return new FavouritesFragment(); 
    } 
    return null; 
} 

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

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    Fragment fragment = (Fragment) super.instantiateItem(container, position); 
    registeredFragments.put(position, fragment); 
    return fragment; 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    registeredFragments.remove(position); 
    super.destroyItem(container, position, object); 
} 

public Fragment getRegisteredFragment(int position) { 
    return registeredFragments.get(position); 
} 

Ora è possibile ottenere registeredFragments dall'esterno

int pos = viewpager.getCurrentItem(); 
Fragment fragment = adapter.getRegisteredFragment(pos); 
switch (pos) { 
    case 0: { 
     ((NPListFragment) fragment).refreshT(); 
     break; 
    } 
    case 1: { 
     ((PListFragment) fragment).refreshK(); 
     break; 
    } 
    case 2: { 
     ((FavouritesFragment) fragment).refreshL(); 
     break; 
    } 
} 
1

Ho risolto questo problema.

Sta succedendo perché l'adattatore si sta inizializzando ogni volta che un nuovo frammento viene richiamato.

Per risolvere questo problema è necessario effettuare una serie di Required Frammento in onCreate metodo

Fragment[] FragmentArray; 
FragmentArray = new Fragment[] {new Fragment 1,new Fragment 2...}; // all fragment goes in array 
... 

get item(int position) 
... 
return FragmentArray[position] 
... 
Fragment1 f= (Fragment1) FragmentArray[0]; 
f.refresh() // call required function 
Problemi correlati