按标签获取片段

时间:2014-07-17 08:09:30

标签: android android-fragments nullpointerexception android-pageradapter

我正在使用 FragmentPagerAdapter 来创建包含不同片段的多页面UI。我想要做的是使用片段的位置找到片段。

我已经应用了查找片段名称标签的方法并使用了.FindFragmentbyTag(),但.FindFragmentbyTag总是返回null值。结构似乎是正确的,所以我不知道为什么我得到空值,请仔细看看,帮助表示赞赏。

这是代码

MainActivity.java
public void onCreate(Bundle savedInstanceState) {
    this.getSupportFragmentManager();
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    MainActivity.instance=this;
    //Initialize pager
    vpPager = (ViewPager)findViewById(R.id.mypager);
    pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
    vpPager.setAdapter(pagerAdapter);
    this.mapFragment = (MapFragment)this.findFragmentByPosition(0);
    this.drFragment = (DRFragment)this.findFragmentByPosition(1);
    this.sensorFragment = (SensorFragment)this.findFragmentByPosition(2);
    ......
}

protected Fragment  findFragmentByPosition(int position) {
    int pagerid = this.vpPager.getId();
    long pagerAdapterid = this.pagerAdapter.getItemId(position);
    return getSupportFragmentManager().findFragmentByTag("android:switcher:" + pagerid + ":" + pagerAdapterid + "");
}

MyPagerAdapter.java
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.View;

public class MyPagerAdapter extends FragmentPagerAdapter {
    private static final String TAG = "TM_PageAdapter";
    private static int numItems = 3;

    public MyPagerAdapter(FragmentManager fragmentManager){
        super(fragmentManager);
    }

    public int getCount() {
        return numItems;
    }

    @Override
    public Fragment getItem(int position) {
        switch(position){
            case 0:
                return MapFragment.newInstance(0, "Map Information");
            case 1:
                return DRFragment.newInstance(1, "DR Information");
            case 2: 
                return SensorFragment.newInstance(2, "Sensor Information");
            default: 
                return null;
        }
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch(position){
            case 0:
                return "Map Information";
            case 1:
                return "DR Information";
            case 2: 
                return "Sensor Information";
            default:
                return null;
        }
    }

    public static String makeFragmentName(int viewId, int index) {
        return "android:switcher:" + viewId + ":" + index;
   }


    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == ((View) arg1);

    }

    @Override
    public Parcelable saveState() {
        return null;
    }

这是.newInstance的代码之一:

public static MapFragment newInstance(int position, String title){
    MapFragment mapFragment = new MapFragment();
    Bundle args = new Bundle();
    args.putInt("current_page", 0);
    args.putString("page_tile", "Map Information");
    mapFragment.setArguments(args);
    return mapFragment;
}

3 个答案:

答案 0 :(得分:3)

在findFragmentByPosition中,您在查找片段时没有使用索引:

getSupportFragmentManager().findFragmentByTag("android:switcher:" + pagerid + ":" + pagerAdapterid + "");

第二个应该是索引,而不是pagerAdapterId。所以正确的代码是:

getSupportFragmentManager().findFragmentByTag("android:switcher:" + pagerid + ":" + position);

也没有必要连接最后一个空字符串。

答案 1 :(得分:1)

我过去使用过这种方法,效果很好。

在适配器中,您可以声明一个实例变量,如下所示:

private Map<Integer, Fragment> mPageReferenceMap = new HashMap<Integer, Fragment>();

在你的getItem()中,在地图中放置片段的引用

mPageReferenceMap.put(position, f);

覆盖InstantiateItem方法:

/**
 * After an orientation change, the fragments are saved in the adapter, and
 * I don't want to double save them: I will retrieve them and put them in my
 * list again here.
 */
@Override
public Object instantiateItem(ViewGroup container, int position) {
   Fragment fragment = (Fragment) super.instantiateItem(container, position);
   mPageReferenceMap.put(position, fragment);
   return fragment;
}

重写onDestroyItem以清理引用:

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

最后根据其位置得到片段:

public Fragment getFragment(int key) {
    return mPageReferenceMap.get(key);
}

希望它有所帮助。

答案 2 :(得分:1)

似乎导致我的引用变为null的事情是因为加载片段是在后台完成的,当我引用这些片段时,加载还没有完成(谢谢Daniel Zolnai因为那个问题,我会给你如果你把它作为答案,请回答正确答案) 我现在对解决方案的想法是:

- 使用(ViewPager).setOffScreenLimit(int limit)

,如果页数很小,请加载所有页面

- 暂停主要活动并等到所有页面都加载完毕然后继续。

现在我被困在第二部分,如果有人知道如何等待或延迟MainActivty加载页面完成或强制加载任务到前台,这对我来说将是一个很大的帮助,谢谢