【问题标题】:Call Tabbed Fragment method from Activity从 Activity 调用 Tabbed Fragment 方法
【发布时间】:2015-04-12 08:44:25
【问题描述】:

我有一个包含三个片段的活动。片段使用 PagerAdapter 使用操作栏选项卡。我想要做的是从主要活动访问活动选项卡式片段中的方法。我已经尝试了下面的代码,但这只是将片段返回为空,所以我猜它无法在选项卡中找到它!

 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 个小时来解决这个问题。

【问题讨论】:

  • 你能展示你的 PagerAdapter 吗?
  • 添加了寻呼机适配器 - 谢谢

标签: android android-fragments tabs fragmentpageradapter


【解决方案1】:

你应该做的是:每个片段只创建一次,然后将它用于所有对 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();
...

【讨论】:

  • 不错的解决方案,但是当我尝试在片段中访问它们时,我得到了视图的空指针异常。仅在我在访问视图之间重置适配器后才会发生这种情况。有什么想法吗?
  • 这将创建另一个空片段,并且它们的视图将为空。您需要注册您之前创建的片段并通过 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);
}

现在你可以从外部获取注册片段

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

【讨论】:

    【解决方案3】:

    我解决了这个问题。

    这是因为每次调用 get item 时适配器都会初始化一个新的 Fragment。

    要解决这个问题,您需要在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
    

    【讨论】:

      【解决方案4】:

      我使用片段管理器来获取片段。我的片段在 ViewPagerAdapter.class 中的视图寻呼机中初始化 -

      @Override
          public Fragment getItem(int i) {
              Fragment fragment = null;
              switch (i) {
                  case 0:
                      fragment = Fragment.instantiate(mContext, Fragment1.class.getName());
                      break;
                  case 1:
                      fragment = Fragment.instantiate(mContext, Fragment2.class.getName());
                      break;
                  case 2:
                      fragment = Fragment.instantiate(mContext, Fragment3.class.getName());
                      break;
              }
              return fragment;
          }
      

      然后在 MainActivity -

      List<Fragment> fragments = getSupportFragmentManager().getFragments();
              if (fragments != null) {
                  for (Fragment fragment : fragments) {
                      if (fragment instanceof Fragment1) {
                          ((Fragment1) fragment).fragmentOne();
                          break;
                      }
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 2012-08-17
        • 1970-01-01
        • 1970-01-01
        • 2017-07-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多