我有一个ViewPager
和三个Fragment
的应用。我正在试图找出如何让当前Fragment
被查看,以便我可以得到它的论点。
我有OnPageChangeListener
抓取当前页面索引,但
ViewPager.getChildAt(int position);
返回View
。此View
与当前Fragment
之间的关系是什么?
答案 0 :(得分:46)
我终于找到了适合我的an answer。基本上,您可以使用标签“android:switcher:”+ R.id.viewpager +“:0”访问viewPager页面的片段。
答案 1 :(得分:18)
我反过来解决了这个问题。 我没有从活动中搜索片段,而是在它的所有者活动的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);
}
}
答案 2 :(得分:5)
编辑 - 不要这样做。如果您有诱惑,请阅读评论,说明为什么这是一个坏主意。
奇怪的是,你还在努力解决这个问题:
扩展FragmentPagerAdapter
。在构造函数中,构建所需的Fragments并将它们存储在Fragments的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];
}
我不确定这是否是普遍接受的做法,但它对我有用。
修改强>
这真的不是一个好方法。如果您计划处理方向更改或您的应用程序进入后台,那么这可能会破坏您的代码。有关详细信息,请阅读此答案下方的评论。而是使用@James的回答
答案 3 :(得分:4)
是的,如果您使用FragmentStatePagerAdapter
,则可以。
ViewPager vp;
//...
YourFragment fragment = (YourFragment) adapter.instantiateItem(vp, vp.getCurrentItem());
答案 4 :(得分:3)
请不要使用
让您的适配器扩展以下FragmentStatePagerWithCurrentAdapter
类,而不是实现getItem
将相同的代码实现到getItemAtIndex
将ViewPager
OnPageChangeListener
设置为适配器的实例。
当您需要访问当前片段时,只需拨打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
答案 5 :(得分:1)
这里已经解释过:http://developer.android.com/guide/topics/fundamentals/fragments.html
在OnCreateView中,您必须返回一个视图来为您的片段绘制UI,我认为这是关系。
此问题可能类似:Get focused View from ViewPager
答案 6 :(得分:1)
你可以这样做: - 在视图分页器适配器的类范围(例如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;
}
答案 7 :(得分:1)
无缝合作的确定答案(但小黑客):
页面片段布局中的某处:
<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();
}
答案 8 :(得分:0)
Jorge Garcia's FragmentStatePagerWithCurrentAdapter是一个非常好的解决方案,但需要稍微改进一下。如果活动被破坏并重新创建以响应配置更改或类似的事件,则不会为片段管理器保存和检索的片段调用getItem。所以我在我的子类中正常覆盖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。
答案 9 :(得分:0)
或者只是将所有碎片保存在地图中:
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);
}
}
答案 10 :(得分:-2)
我认为使用此
有更好的方法 Log.i(TAG, "getCurrentItem " + mViewPager.getCurrentItem());
可以获取当前的显示片段页面。