是否有可能访问ViewPager正在查看的当前片段?

我有一个ViewPager和三个Fragment的应用程序。 我试图弄清楚如何让当前Fragment被观看,这样我就可以得到它的论点。

我有一个OnPageChangeListener抓取当前页面的索引,但是

 ViewPager.getChildAt(int position); 

返回一个View 。 这个View和现在的Fragment之间有什么关系?

我终于find了一个适合我的答案 。 基本上,您可以使用标签“android:switcher:”+ R.id.viewpager +“:0”来访问viewPager页面的片段。

我反过来解决了这个问题。 我不是从活动中search片段,而是在它的onAttach()方法中注册片段,并在onStop()方法中取消注册。 基本思路:

分段:

 @Override public void onAttach(Activity activity) { super.onAttach(activity); try{ mActivity = (IMyActivity)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString() +" must be a IMyActivity"); } mActivity.addFragment(this); } @Override public void onStop() { mActivity.removeFragment(this); super.onStop(); } 

IMyActivity:

 public interface IFriendActivity { public void addFragment(Fragment f); public void removeFragment(Fragment f); } 

MyActivity:

 public class MyActivity implements IMyActivity{ [...] @Override public void addFragment(Fragment f) { mFragments.add(f); } @Override public void removeFragment(Fragment f) { mFragments.remove(f); } } 

编辑 – 不要这样做。 如果你有兴趣,请阅读评论为什么这是一个坏主意。

在奇怪的机会,你仍然试图解决这个问题:

扩展FragmentPagerAdapter 。 在构造函数中,构build您需要的碎片并将它们存储在碎片的List(array / ArrayList)中。

 private final int numItems = 3; Fragment[] frags; public SwipeAdapter (FragmentManager fm) { super(fm); //Instantiate the Fragments frags = new Fragment[numItems]; Bundle args = new Bundle(); args.putString("arg1", "foo"); frags[0] = new MyFragment(); frags[1] = new YourFragment(); frags[2] = new OurFragment(); frags[2].setArguments(args); } 

那么对于getItem(int position) ,你可以做类似的事情

 public Fragment getItem(int position) { return frags[position]; } 

我不确定这是否是普遍接受的方式,但它对我有效。

编辑

这真的不是一个好的方法。 如果您打算处理方向更改或您的应用程序进入后台,那么这可能会破坏您的代码。 请阅读下面的评论以获取更多信息。 而是用@詹姆斯的答案

是的,如果您使用FragmentStatePagerAdapter ,则可以。

 ViewPager vp; //... YourFragment fragment = (YourFragment) adapter.instantiateItem(vp, vp.getCurrentItem()); 

请不要使用这个

使您的适配器扩展以下FragmentStatePagerWithCurrentAdapter类,而不是实现getItem实现相同的代码到getItemAtIndex

ViewPager OnPageChangeListener设置为适配器的实例。

当你需要访问当前的Fragment时,你只需调用adapter.getCurrentItem()

 package your.package; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.SparseArray; import android.view.ViewGroup; public abstract class FragmentStatePagerWithCurrentAdapter extends FragmentStatePagerAdapter implements OnPageChangeListener { int currentPage = 0; private SparseArray<Fragment> mPageReferenceMap = new SparseArray<Fragment>(); public FragmentStatePagerWithCurrentAdapter(FragmentManager fm) { super(fm); } @Override public final Fragment getItem(int index) { Fragment myFragment = getItemAtIndex(index); mPageReferenceMap.put(index, myFragment); return myFragment; } public abstract Fragment getItemAtIndex(int index); @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); mPageReferenceMap.remove(Integer.valueOf(position)); } public Fragment getCurrentItem() { return mPageReferenceMap.get(currentPage); } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int newPageIndex) { currentPage = newPageIndex; } } 

我用作参考以下博客文章: http : //tamsler.blogspot.com/2011/11/android-viewpager-and-fragments-part-ii.html

这里已经解释了: http : //developer.android.com/guide/topics/fundamentals/fragments.html

在OnCreateView你必须返回一个视图来绘制你的片段的UI,我认为这是关系。

此外,这个问题可能是类似的: 从ViewPager获得专注的视图

您可以这样做: – 在视图寻呼机适配器(如PagerAdapter,FragmentStatePagerAdapter …)的类范围覆盖方法instantiateItem:

 @Override public Object instantiateItem(ViewGroup container, int position) { final Fragment frag = (Fragment) super.instantiateItem(container, position); if(frag instanceof ListNoteOfTypeFragment){ final ListNoteOfTypeFragment listNoteOfTypeFragment = (ListNoteOfTypeFragment) frag; //do whatever you want with your fragment here listNoteOfTypeFragment.setNoteChangeListener(mListener); } return frag; } 

确切的答案,无缝工作(但小破解):

页面片段布局中的某处:

 <FrameLayout android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone" android:id="@+id/fragment_reference"> <View android:layout_width="0dp" android:layout_height="0dp" android:visibility="gone"/> </FrameLayout> 

在片段的onCreateView()中:

 ... View root = inflater.inflate(R.layout.fragment_page, container, false); ViewGroup ref = (ViewGroup)root.findViewById(R.id.fragment_reference); ref.setTag(this); ref.getChildAt(0).setTag("fragment:" + pageIndex); return root; 

以及从ViewPager返回Fragment的方法(如果存在):

 public Fragment getFragment(int pageIndex) { View w = mViewPager.findViewWithTag("fragment:" + pageIndex); if (w == null) return null; View r = (View) w.getParent(); return (Fragment) r.getTag(); } 

Jorge Garcia的FragmentStatePagerWithCurrentAdapter是一个非常好的解决scheme,但是需要稍微改进。 如果活动被破坏并重新创build,以响应configuration更改或类似的事情,getItem将不会被片段pipe理器保存和检索的片段调用。 所以我重写getItem通常在我的子类,我把下面的FragmentStatePagerWithCurrentAdapter

 @Override public Object instantiateItem(ViewGroup container, int position) { Object item = super.instantiateItem(container, position); if ( item instanceof Fragment ) { pageReferenceMap.put(position, (Fragment)item); } return item; } 

每当访问该位置的片段时,都会调用instantiateItem。

或者把所有碎片保存在地图中:

 public class MyFragment extends Fragment implements OnPageChangeListener { private ViewPager viewPager; private FragmentStatePagerAdapter viewAdapter; private View rootView; private Map<Integer, Fragment> fragments = new HashMap<Integer, Fragment>(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { rootView = inflater.inflate(R.layout.introdution, container, false); viewPager = (ViewPager) rootView.findViewById(R.id.pager); viewAdapter = new ViewAdapter(getFragmentManager()); viewPager.setAdapter(viewAdapter); viewPager.addOnPageChangeListener(this); return rootView; } private class ViewAdapter extends FragmentStatePagerAdapter { public ViewAdapter(FragmentManager fragmentManager) { super(fragmentManager); } @Override public Fragment getItem(int position) { Fragment result = null; switch (position) { case 0: result = Fragment1.newInstance(); break; case 1: result = Fragment2.newInstance(); break; } if (result != null) fragments.put(position, result); return result; } @Override public int getCount() { return 2; } } @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position) { Fragment currentFragment = fragments.get(position); } } 

我认为有更好的方法来使用这个

Log.i(TAG, "getCurrentItem " + mViewPager.getCurrentItem());

可以得到当前的显示片段页面。