2015-04-12 15 views
5

У меня есть одно действие, состоящее из трех фрагментов. Фрагменты используют вкладки панели действий с помощью PagerAdapter. То, что я хочу сделать, - это доступ к методу в активном фрагменте с вкладками из основного действия. Я пробовал приведенный ниже код, но это просто возвращает фрагмент как null, поэтому я думаю, что он не может найти его внутри вкладок!Вызовите метод с вкладками с фрагментами из Activity

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; 
} 

} Может кто-нибудь посоветовать? Я потратил около 6 часов на это, я просто не делаю никакого прогресса, разрешая это.

+0

Можете ли вы показать свою PagerAdapter? –

+0

добавлен пейджер-адаптер - спасибо – user2029541

ответ

13

Что вам нужно сделать: создать только один раз каждый фрагмент, а затем передать его для всех вызовов метода getItem.

Например:

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; 
} 

} 

Теперь, даже вы в вашей деятельности вы можете позвонить getItem

Вам просто нужно, чтобы бросить его в реальный класс фрагмента, если вы хотите, чтобы вызвать определенный метод ,

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

приятное решение, но я получаю исключение нулевого указателя из представлений, когда я пытался получить к ним доступ в фрагменте. Это происходит только после того, как я сбросил адаптер между доступом к представлениям. Есть идеи? – VinKrish

+1

Это создаст еще один пустой фрагмент, и их представления будут пустыми. Вам необходимо зарегистрировать ранее созданные фрагменты и получить к ним доступ методом getter. –

2

Вам необходимо зарегистрировать свои фрагменты во время заселения, а затем получить к ним доступ извне.

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); 
} 

Теперь вы можете получить registeredFragments от внешнего

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

Я решил эту проблему.

Это происходит потому, что адаптер инициализируется каждый раз, когда новый фрагмент появляется при вызове элемента.

Чтобы решить эту проблему вам нужно сделать массив нужный фрагмент в onCreate методом

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