怎么在父fragment中获取viewpager中的子fragment

2,608 阅读1分钟

ViewPager中嵌套Fragment的时候,我们通常使用的是FragmentPagerAdapter , 在 FragmentPagerAdapter 源码中会通过 instantiateItem 生成界面,其代码如下:

public Object instantiateItem(ViewGroup container, int position) {
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }
    final long itemId = getItemId(position);
    // Do we already have this fragment?
    String name = makeFragmentName(container.getId(), itemId);
    Fragment fragment = mFragmentManager.findFragmentByTag(name);
    if (fragment != null) {
        if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
        mCurTransaction.attach(fragment);
    } else {
        fragment = getItem(position);
        if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
        mCurTransaction.add(container.getId(), fragment,
                makeFragmentName(container.getId(), itemId));
    }
    if (fragment != mCurrentPrimaryItem) {
        fragment.setMenuVisibility(false);
        fragment.setUserVisibleHint(false);
    }
    return fragment;
}




解决方法:就是Adapter中设置tag,然后暴露方法给父fragment调用,或者在父fragment中通过tag拿到子ChildFragment

//父fragment中通过tag拿到子ChildFragment

 VpAdapter adapter = (VpAdapter) (view_pager.getAdapter());
        if (adapter != null) {
            List<String> tags = adapter.tags;
            ChildFragment gameFragment = (ChildFragment) getChildFragmentManager().findFragmentByTag(tags.get(mCurrentIndex));
          
        }
        
        

// Adapter中设置tag,然后暴露方法给父fragment调用

class VpAdapter extends FragmentPagerAdapter {
private final String[]        titles;
private final FragmentManager fragmentManager;
List<String> tags = new ArrayList<>();

public VpAdapter(FragmentManager fm, String[] titles) {
    super(fm);
    fragmentManager = fm;
    this.titles = titles;
}

@Override
public int getCount() {
    return titles.length;
}

@Override
public Fragment getItem(int position) {
    return Fragment_VpItem.newInstance(position);   //多个页面的布局样式一致,所以需要根据position展示不同的内容
}

@Override
public CharSequence getPageTitle(int position) {
    return titles[position];
}

@Override
public Object instantiateItem(ViewGroup container, int positon) {
    //创建tag并存储到集合中
     long itemId = getItemId(position);
     //注意,这里传入itemID,不是position,传position拿不到的
    String fragmentNameTag = makeFragmentName(container.getId(), itemId);
    if (!tags.contains(fragmentNameTag)) {
        tags.add(fragmentNameTag);
    }
    return super.instantiateItem(container, pageIndex);
}

/**
 * 创建Fragment的名称也就是tag,该方法源自 FragmentPagerAdapter的源码
 */
private static String makeFragmentName(int viewId, long id) {
    return "android:switcher:" + viewId + ":" + id;
}

/**
 * 父fragment调用此方法刷新数据
 *
 * @param position     列表中被点击条目的位置
 * @param curPageIndex 当前正在展示的页面
 */
public void refreshMofifiedPageData(int position, int curPageIndex) {
    for (int i = 0; i < tags.size(); i++) {
        Fragment_VpItem fragment = (Fragment_VpItem) fragmentManager.findFragmentByTag(tags.get(i));
        fragment.refreshData(position, curPageIndex);
    }
}

}