如何确定何时片段在viewpager禁止滑动变得可见

ActionBarSherlock,ViewPager,TabsAdapter嵌套标签片段-java,安卓android,actionbarsherlock,片段fragment-CodeGo.net
ActionBarSherlock,ViewPager,TabsAdapter嵌套标签片段
我有一个ViewPager和TabsAdapter一个ActionBarSherlock。它工作得很好,但现在我试图从一个装在“表1”另一个“推”
该行为应该是这样的:
我有3选项卡在我的应用程序,当启动我看到的优先个选项卡,其中一个带按钮是它
按下优先个选项卡的按钮,则在优先个选项卡应及时更换,另应显示
我试过这个,但是我有一个黑色的更换时。
public class FragmentDemoActivity extends SherlockFragmentActivity {
CustomViewPager mViewP
TabsAdapter mTabsA
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
mViewPager = (CustomViewPager)findViewById(R.id.pager);
mViewPager.setSwipingEnabled(false);
mTabsAdapter = new TabsAdapter(this, bar, mViewPager);
mTabsAdapter.addTab(bar.newTab().setText("tab1"),
FragmentA.class, null);
mTabsAdapter.addTab(bar.newTab().setText("tab2"),
FragmentB.class, null);
setTitle(R.string.app_name);
if (savedInstanceState != null) {
bar.setSelectedNavigationItem(savedInstanceState.getInt("tab"));
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("tab", getSupportActionBar().getSelectedNavigationIndex());
public static class TabsAdapter extends FragmentPagerAdapter
implements ViewPager.OnPageChangeListener, ActionBar.TabListener {
private final Context mC
private final ActionBar mB
private final ViewPager mViewP
private final ArrayList&TabInfo& mTabs = new ArrayList&TabInfo&();
static final class TabInfo {
private final Class&?&
private final B
TabInfo(Class&?& _class, Bundle _args) {
public TabsAdapter(FragmentActivity activity, ActionBar bar, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext =
mViewPager =
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
public void addTab(ActionBar.Tab tab, Class&? extends Fragment& clss, Bundle args) {
TabInfo info = new TabInfo(clss, args);
tab.setTag(info);
tab.setTabListener(this);
mTabs.add(info);
mBar.addTab(tab);
notifyDataSetChanged();
public int getCount() {
return mTabs.size();
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
public void onPageSelected(int position) {
mBar.setSelectedNavigationItem(position);
public void onPageScrollStateChanged(int state) {
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Object tag = tab.getTag();
for (int i=0; i&mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i,false);
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
public void onTabReselected(Tab tab, FragmentTransaction ft) {
public class FragmentA extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle saved)
return inflater.inflate(R.layout.frag_a, group, false);
public void onActivityCreated (Bundle savedInstanceState)
super.onActivityCreated(savedInstanceState);
button = (Button) getActivity().findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
FragmentB f1 = new FragmentB();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.pager, f1,"newTag");
ft.show(f1);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commit();
我是新加入的Android CodeGo.net,所以我会很高兴,如果能够,我已经研究了很多寻找一个解决方案,但结果并不如我所料。
我当前的项目:
本文地址 :CodeGo.net/544150/
-------------------------------------------------------------------------------------------------------------------------
1. 我抓住了!
解释一下,你需要把一个id在你的版面要更换,我的例子:
&FrameLayout xmlns:android=" CodeGo.net
android:id="@+id/Framelay"
android:layout_width="match_parent"
android:layout_height="wrap_content" &
android:id="@+id/txtSearchTopic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:text="TextView" /&
&/FrameLayout&
所以,我只是把我的:android:ID=“@+ID /
然后,我这个ID来代替新是什么,这一切布局内的内容将被新的取代,因为我叫
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
DetailFragment fragment3 = new DetailFragment();
fragmentTransaction.replace(R.id.Framelay, fragment3);
本文标题 :ActionBarSherlock,ViewPager,TabsAdapter嵌套标签片段
本文地址 :CodeGo.net/544150/
Copyright (C) 2017 CodeGo.net您的举报已经提交成功,我们将尽快处理,谢谢!
我做过ViewPager中嵌套ListView,一切正常你还是贴出自己的代码吧
1.设置GridView的DataKeyNames="id"
2.在事件里写
for (int i = 0; i & GridView1.Rows.C...
用Adobe Reader只可以读取而无法修改文档,亦即无法修改业已生成的PDF文档,出现错序很无奈。
你可以从网上下载软件,我用的是Adobe Acro...
内存信息没有清理
大家还关注
获取西瓜影音网页嵌套代码 (代码需要放置...在ListFragment作为ViewPager的一部分更新数据-java,安卓android,android-fragments,android-viewpager-CodeGo.net
在ListFragment作为ViewPager的一部分更新数据
我在Android上卷兼容性ViewPager。我有一堆数据,这些数据将被显示在我的ViewPager不同的页面不同的方式。到目前为止,我只是有3个实例,但在未来我将有不同的ViewPager 3个实例是一个垂直的手机屏幕上,该列表是不是并排侧。
现在(在启动一个单独的整版活动按钮通过它返回和FragentActivity修改数据,将其保存,然后尝试更新其ViewPager所有的views CodeGo.net,这是我在这里卡住了。
public class ProgressMainActivity extends FragmentActivity
MyAdapter mA
ViewPager mP
public void onCreate(Bundle savedInstanceState)
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.viewpager);
mPager.setAdapter(mAdapter);
protected void onActivityResult(int requestCode, int resultCode, Intent data)
updateFragments();
public void updateFragments()
//Attempt 1:
//mAdapter.notifyDataSetChanged();
//mPager.setAdapter(mAdapter);
//Attempt 2:
//HomeListFragment fragment = (HomeListFragment) getSupportFragmentManager().findFragmentById(mAdapter.fragId[0]);
//fragment.updateDisplay();
public static class MyAdapter extends FragmentPagerAdapter implements
TitleProvider
int[] fragId = {0,0,0,0,0};
public MyAdapter(FragmentManager fm)
super(fm);
public String getTitle(int position){
return titles[position];
public int getCount(){
return titles.
public Fragment getItem(int position)
Fragment frag = HomeListFragment.newInstance(position);
//Attempt 2:
//fragId[position] = frag.getId();
public int getItemPosition(Object object) {
return POSITION_NONE; //To make notifyDataSetChanged() do something
public class HomeListFragment extends ListFragment
public static HomeListFragment newInstance(int num)
HomeListFragment f = new HomeListFragment();
现在,你可以看到,我的优先次尝试是notifyDataSetChanged对整个这表明更新我得到了一个IllegalStateException数据,但其他人:的onSaveInstanceState后无法执行此操作。
我的第二次尝试involed试图调用一个更新函数,但我在的getId返回的getItem 0。按我试图通过文档
使用获得的参考
但我不知道的标记或id我我有一个android:ID=“@+ID / viewpager”为ViewPager和android:ID=“@android:ID /列表”我在布局的ListView,但我不认为这些
所以,我怎么能要么一)安全地更新整个viewpager一次过(理想情况下返回到页面,他是在之前)-即在屏幕上看到的变化是OK。
或最好,B)调用每个受影响的一个函数来手动更新ListView中。
任何帮助将欣然接受!
本文地址 :CodeGo.net/353532/
-------------------------------------------------------------------------------------------------------------------------
1. 好吧,我想我已经找到了一种方法来在我自己的问题进行请求B),所以我将分享他人的利益。内部的ViewPager标签的表单为“android:切换:VIEWPAGER_ID:指数”,其中VIEWPAGER_ID是R.id.viewpager在XML布局和INDEX是在viewpager的位置。因此,如果位置是已知的(例如0),能执行在
HomeListFragment fragment =
(HomeListFragment) getSupportFragmentManager().findFragmentByTag(
"android:switcher:"+R.id.viewpager+":0");
if(fragment != null) // could be null if not instantiated yet
if(fragment.getView() != null)
// no need to call if fragment's onDestroyView()
//has since been called.
fragment.updateDisplay(); // do what updates are required
我不知道这是否是这样做的一个有效的方法,但它会做 CodeGo.net,直到更好的建议。
Barkside的回答与工作FragmentPagerAdapter但不与工作FragmentStatePagerAdapter,它不设置标签上把它传递给FragmentManager。
同FragmentStatePagerAdapter似乎我们可以通过使用其instantiateItem(ViewGroup container, int position)打电话。它返回到参考位置position。如果FragmentStatePagerAdapter已持有参考问题,instantiateItem只是返回引用,并且不调用getItem()重新实例化它。
因此,假设,我目前在看#50,并要访问#49。由于他们接近,有一个很好的机会在#49将已经实例化的。所以,
ViewPager pager = findViewById(R.id.viewpager);
FragmentStatePagerAdapter a = (FragmentStatePagerAdapter) pager.getAdapter();
MyFragment f49 = (MyFragment) a.instantiateItem(pager, 49)
如果您在以下页面上的第二个解决方案,轨迹所有的“活动”页面,为更好:
从barkside答案是太哈克
你把所有的“活动”页面的轨道。在这种情况下,你轨迹的ViewPager在该页面..
public Fragment getItem(int index) {
Fragment myFragment = MyFragment.newInstance();
mPageReferenceMap.put(index, myFragment);
return myF
为了避免保持一个引用到“非活动”页面,我们需要将destroyItem(...)方法:
public void destroyItem(View container, int position, Object object) {
super.destroyItem(container, position, object);
mPageReferenceMap.remove(position);
...当你需要访问当前可见的页面,你再拨打:
int index = mViewPager.getCurrentItem();
MyAdapter adapter = ((MyAdapter)mViewPager.getAdapter());
MyFragment fragment = adapter.getFragment(index);
...其中MyAdapter的方法看起来像这样:
public MyFragment getFragment(int key) {
return mPageReferenceMap.get(key);
试图记录每个实例化的标签。
public class MPagerAdapter extends FragmentPagerAdapter {
private Map&Integer, String& mFragmentT
private FragmentManager mFragmentM
public MPagerAdapter(FragmentManager fm) {
super(fm);
mFragmentManager =
mFragmentTags = new HashMap&Integer, String&();
public int getCount() {
return 10;
public Fragment getItem(int position) {
return Fragment.instantiate(mContext, AFragment.class.getName(), null);
public Object instantiateItem(ViewGroup container, int position) {
Object obj = super.instantiateItem(container, position);
if (obj instanceof Fragment) {
// record the fragment tag here.
Fragment f = (Fragment)
String tag = f.getTag();
mFragmentTags.put(position, tag);
public Fragment getFragment(int position) {
String tag = mFragmentTags.get(position);
if (tag == null)
return mFragmentManager.findFragmentByTag(tag);
好了,通过上面的@barkside测试后,我无法得到它与我的应用程序工作。然后,我的IOSched2012一个viewpager还有,就是在那里,我发现我的解决方案。它的任何ID或标签,因为这些不被存储viewpager在易于访问的方式。
下面是来自IOSched应用程序的重要组成部分要特别注意的,因为其中存在的关键。:
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Since the pager fragments don't have known tags or IDs, the only way to persist the
// reference is to use putFragment/getFragment. Remember, we're not persisting the exact
// Fragment instance. This mechanism simply gives us a way to persist access to the
// 'current' fragment instance for the given fragment (which changes across orientation
// changes).
// The outcome of all this is that the "Refresh" menu button refreshes the stream across
// orientation changes.
if (mSocialStreamFragment != null) {
getSupportFragmentManager().putFragment(outState, "stream_fragment",
mSocialStreamFragment);
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (mSocialStreamFragment == null) {
mSocialStreamFragment = (SocialStreamFragment) getSupportFragmentManager()
.getFragment(savedInstanceState, "stream_fragment");
和你存储实例Fragments在FragmentPagerAdapter像这样:
private class HomePagerAdapter extends FragmentPagerAdapter {
public HomePagerAdapter(FragmentManager fm) {
super(fm);
public Fragment getItem(int position) {
switch (position) {
return (mMyScheduleFragment = new MyScheduleFragment());
return (mExploreFragment = new ExploreFragment());
return (mSocialStreamFragment = new SocialStreamFragment());
此外,为了保护您的Fragment调用像这样:
if (mSocialStreamFragment != null) {
mSocialStreamFragment.refresh();
您可以复制FragmentPagerAdapter和修改源代码,添加getTag()方法
public abstract class AppFragmentPagerAdapter extends PagerAdapter {
private static final String TAG = "FragmentPagerAdapter";
private static final boolean DEBUG =
private final FragmentManager mFragmentM
private FragmentTransaction mCurTransaction =
private Fragment mCurrentPrimaryItem =
public AppFragmentPagerAdapter(FragmentManager fm) {
mFragmentManager =
public abstract Fragment getItem(int position);
public void startUpdate(ViewGroup container) {
public Object instantiateItem(ViewGroup container, int position) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
final long itemId = getItemId(position);
String name = getTag(position);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
if (fragment != null) {
if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
mCurTransaction.attach(fragment);
fragment = getItem(position);
if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
mCurTransaction.add(container.getId(), fragment,
getTag(position));
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
fragment.setUserVisibleHint(false);
public void destroyItem(ViewGroup container, int position, Object object) {
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object
+ " v=" + ((Fragment) object).getView());
mCurTransaction.detach((Fragment) object);
public void setPrimaryItem(ViewGroup container, int position, Object object) {
Fragment fragment = (Fragment)
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
mCurrentPrimaryItem.setUserVisibleHint(false);
if (fragment != null) {
fragment.setMenuVisibility(true);
fragment.setUserVisibleHint(true);
mCurrentPrimaryItem =
public void finishUpdate(ViewGroup container) {
if (mCurTransaction != null) {
mitAllowingStateLoss();
mCurTransaction =
mFragmentManager.executePendingTransactions();
public boolean isViewFromObject(View view, Object object) {
return ((Fragment) object).getView() ==
public Parcelable saveState() {
public void restoreState(Parcelable state, ClassLoader loader) {
public long getItemId(int position) {
private static String makeFragmentName(int viewId, long id) {
return "android:switcher:" + viewId + ":" +
protected abstract String getTag(int position);
然后延伸,覆盖这些需要害怕的Android组的变化FragmentPageAdapter在未来的源代码
class TimeLinePagerAdapter extends AppFragmentPagerAdapter {
List&Fragment& list = new ArrayList&Fragment&();
public TimeLinePagerAdapter(FragmentManager fm) {
super(fm);
list.add(new FriendsTimeLineFragment());
list.add(new MentionsTimeLineFragment());
list.add(new CommentsTimeLineFragment());
public Fragment getItem(int position) {
return list.get(position);
protected String getTag(int position) {
List&String& tagList = new ArrayList&String&();
tagList.add(FriendsTimeLineFragment.class.getName());
tagList.add(MentionsTimeLineFragment.class.getName());
tagList.add(CommentsTimeLineFragment.class.getName());
return tagList.get(position);
public int getCount() {
return list.size();
我刚才已经回答了类似的在不同的线程。也许这会帮助在这里了。
一个从ViewPager访问活动
而不是回国POSITION_NONE标签找有更好的清洁解决方案。请检查:Android的ViewPager-不能动态更新
我想给我的方法的情况下,它可以帮助其他人:
这是我的呼机adapter:
public class CustomPagerAdapter extends FragmentStatePagerAdapter{
private Fragment[]
public CustomPagerAdapter(FragmentManager fm) {
super(fm);
fragments = new Fragment[]{
new FragmentA(),
new FragmentB()
public Fragment getItem(int arg0) {
return fragments[arg0];
public int getCount() {
return fragments.
在我的活动我的:
public class MainActivity {
private ViewPager view_
private CustomPagerA
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = new CustomPagerAdapter(getSupportFragmentManager());
view_pager = (ViewPager) findViewById(R.id.pager);
view_pager.setAdapter(adapter);
view_pager.setOnPageChangeListener(this);
然后得到当前我要做的就是:
int index = view_pager.getCurrentItem();
Fragment currentFragment = adapter.getItem(index);
你为什么不给你的ID吗?这就是我所做的,在对其中包含它们的活动的XML布局,在这一点上发现一个被标识工作正常。
本文标题 :在ListFragment作为ViewPager的一部分更新数据
本文地址 :CodeGo.net/353532/
Copyright (C) 2017 CodeGo.net替换片段里面ViewPager-安卓android,视图view,android-fragments,android-viewpager,pager-CodeGo.net
替换片段里面ViewPager
我正在寻找的实现是更换一个定位在ViewPager的优先页,用一个又一个。
两页的寻呼机。优先个是,第二个是在单击优先页的按钮。我想与更换
下面有我的代码。
public class FragmentPagerActivity extends FragmentActivity {
static final int NUM_ITEMS = 2;
MyAdapter mA
ViewPager mP
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_pager);
mAdapter = new MyAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
* Pager Adapter
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
public int getCount() {
return NUM_ITEMS;
public Fragment getItem(int position) {
if(position == 0) {
return FirstPageFragment.newInstance();
return SecondPageFragment.newInstance();
* Second Page FRAGMENT
public static class SecondPageFragment extends Fragment {
public static SecondPageFragment newInstance() {
SecondPageFragment f = new SecondPageFragment();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Log.d("DEBUG", "onCreateView");
return inflater.inflate(R.layout.second, container, false);
* FIRST PAGE FRAGMENT
public static class FirstPageFragment extends Fragment {
public static FirstPageFragment newInstance() {
FirstPageFragment f = new FirstPageFragment();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Log.d("DEBUG", "onCreateView");
View root = inflater.inflate(R.layout.first, container, false);
button = (Button) root.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.first_fragment_root_id, NextFragment.newInstance());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
* Next Page FRAGMENT in the First Page
public static class NextFragment extends Fragment {
public static NextFragment newInstance() {
NextFragment f = new NextFragment();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Log.d("DEBUG", "onCreateView");
return inflater.inflate(R.layout.next, container, false);
......这里的xml文件
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android=" CodeGo.net
android:orientation="vertical" android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent" android:layout_height="match_parent"&
&android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"&
&/android.support.v4.view.ViewPager&
&/LinearLayout&
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout xmlns:android=" CodeGo.net
android:id="@+id/first_fragment_root_id"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"&
&Button android:id="@+id/button"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:text="to next"/&
&/LinearLayout&
现在的问题......该ID应在
trans.replace(R.id.first_fragment_root_id, NextFragment.newInstance());
如果R.id.的作品,但层次结构查看器显示了一个奇怪的现象,如下图所示。
在开始的情况是
之后的情况
正如你可以看到有错的,我希望找到如图中的优先张照片的状态我更换后的
本文地址 :CodeGo.net/365517/
-------------------------------------------------------------------------------------------------------------------------
1. 还有,这并不需要修改的源代码另一种解决方案ViewPager和FragmentStatePagerAdapter和它的工作原理与FragmentPagerAdapter基类的作者。
我想首先回答了笔者的问题是关于哪个ID,他是容器的ID,即认为寻呼机本身的ID。然而,正如你可能已经注意到自己,使用该ID在你的代码没有什么发生。我会解释为什么:
首先,使ViewPager重新填充的页面 CodeGo.net,你需要调用notifyDataSetChanged()驻留在您的adapter的基类。
第二,ViewPager使用getItemPosition()要检查哪些页面应该被销毁,哪些应该保留。该函数的默认总是返回POSITION_UNCHANGED,这ViewPager保留所有当前的页面,因此没有附加新页面。使工作,getItemPosition()需要在您的adapter被覆盖,必须返回POSITION_NONE当与一个老叫,被隐藏,如
这是您的adapter总是需要知道其中应显示在位置0,FirstPageFragment或NextFragment。这样做的一个方法是创建时提供一个监听器FirstPageFragment,这时候才切换,我认为这虽然是一个好东西,让你的adapter处理所有开关和呼叫将被称为ViewPager和FragmentManager。
三,FragmentPagerAdapter缓存由这是从位置导出,所以,如果有一个在位置0,它不会被即使类是新的替换。有两种解决方法,但最简单的是remove()函数FragmentTransaction,这将删除其标记为好。
这是一个大量的文字,这里是应该在你的情况是代码:
public class MyAdapter extends FragmentPagerAdapter
static final int NUM_ITEMS = 2;
private final FragmentManager mFragmentM
private Fragment mFragmentAtPos0;
public MyAdapter(FragmentManager fm)
super(fm);
mFragmentManager =
public Fragment getItem(int position)
if (position == 0)
if (mFragmentAtPos0 == null)
mFragmentAtPos0 = FirstPageFragment.newInstance(new FirstPageFragmentListener()
public void onSwitchToNextFragment()
mFragmentManager.beginTransaction().remove(mFragmentAtPos0).commit();
mFragmentAtPos0 = NextFragment.newInstance();
notifyDataSetChanged();
return mFragmentAtPos0;
return SecondPageFragment.newInstance();
public int getCount()
return NUM_ITEMS;
public int getItemPosition(Object object)
if (object instanceof FirstPageFragment && mFragmentAtPos0 instanceof NextFragment)
return POSITION_NONE;
return POSITION_UNCHANGED;
public interface FirstPageFragmentListener
void onSwitchToNextFragment();
希望这可以帮助任何人!
由于日的,repacing在ViewPager似乎有很多更容易。谷歌发布Android 4.2与嵌套的支持,它也支持新的Android支持库V11因此这将一路工作,回到1.6
这是非常类似的,以更换的正常方式,除了它似乎工作除了当点击后退按钮嵌套backstack不弹出。按照该链接的问题的解决方案,您需要手动调用上的所以,你需要重写onBackPressed的ViewPager活动在那里你会得到ViewPager的电流,并呼吁它的()子管理者。
获取当前正在显示的是一个有点哈克,以及,这个肮脏的“android:切换:VIEWPAGER_ID:INDEX”的解决方案,但你也可以把所有的ViewPager自己的轨道在此页面上的第二个解决方案解释。
所以这里是我的ViewPager 4 ListViews代码的时候点击一排ViewPager显示详细视图,并用后退按钮的工作。我试着只包括相关代码为简便起见所以留下,如果你想上传到GitHub上完整的应用程序。
public class HomeActivity extends SherlockFragmentActivity {
FragmentAdapter mA
ViewPager mP
TabPageIndicator mI
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mAdapter = new FragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager)findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mIndicator = (TabPageIndicator)findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
// This the important bit to make sure the back button works when you're nesting fragments. Very hacky, all it takes is some Google engineer to change that ViewPager view tag to break this in a future Android update.
public void onBackPressed() {
Fragment fragment = (Fragment) getSupportFragmentManager().findFragmentByTag("android:switcher:" + R.id.pager + ":"+mPager.getCurrentItem());
if (fragment != null) // could be null if not instantiated yet
if (fragment.getView() != null) {
// Pop the backstack on the ChildManager if there is any. If not, close this activity as normal.
if (!fragment.getChildFragmentManager().popBackStackImmediate()) {
class FragmentAdapter extends FragmentPagerAdapter {
public FragmentAdapter(FragmentManager fm) {
super(fm);
public Fragment getItem(int position) {
switch (position) {
return ListProductsFragment.newInstance();
return ListActiveSubstancesFragment.newInstance();
return ListProductFunctionsFragment.newInstance();
return ListCropsFragment.newInstance();
public int getCount() {
public class ListProductsFragment extends SherlockFragment {
private ListV
public static ListProductsFragment newInstance() {
ListProductsFragment f = new ListProductsFragment();
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View V = inflater.inflate(R.layout.list, container, false);
list = (ListView)V.findViewById(android.R.id.list);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView&?& parent, View view,
int position, long id) {
// This is important bit
Fragment productDetailFragment = FragmentProductDetail.newInstance();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.addToBackStack(null);
transaction.replace(R.id.products_list_linear, productDetailFragment).commit();
基于@wize的回答,这是我发现的有用和优雅,我可以实现我想要的部分,我希望cability回去一次更换优先个。我实现了它咬修改了一下他的代码。
public static class MyAdapter extends FragmentPagerAdapter {
private final class CalendarPageListener implements
CalendarPageFragmentListener {
public void onSwitchToNextFragment() {
mFragmentManager.beginTransaction().remove(mFragmentAtPos0)
.commit();
if (mFragmentAtPos0 instanceof FirstFragment){
mFragmentAtPos0 = NextFragment.newInstance(listener);
}else{ // Instance of NextFragment
mFragmentAtPos0 = FirstFragment.newInstance(listener);
notifyDataSetChanged();
CalendarPageListener listener = new CalendarPageListener();;
private Fragment mFragmentAtPos0;
private FragmentManager mFragmentM
public MyAdapter(FragmentManager fm) {
super(fm);
mFragmentManager =
public int getCount() {
return NUM_ITEMS;
public int getItemPosition(Object object) {
if (object instanceof FirstFragment && mFragmentAtPos0 instanceof NextFragment)
return POSITION_NONE;
if (object instanceof NextFragment && mFragmentAtPos0 instanceof FirstFragment)
return POSITION_NONE;
return POSITION_UNCHANGED;
public Fragment getItem(int position) {
if (position == 0)
return Portada.newInstance();
if (position == 1) { // Position where you want to replace fragments
if (mFragmentAtPos0 == null) {
mFragmentAtPos0 = FirstFragment.newInstance(listener);
return mFragmentAtPos0;
if (position == 2)
return Clasificacion.newInstance();
if (position == 3)
return Informacion.newInstance();
public interface CalendarPageFragmentListener {
void onSwitchToNextFragment();
以批判者的简单定义类型的静态字段,CalendarPageFragmentListener并且通过初始化newInstance对应和调用方法FirstFragment.pageListener.onSwitchToNextFragment()或NextFragment.pageListener.onSwitchToNextFragment()respictevely。
希望这是明确的和有益的。
最好的问候。
要更换内部的ViewPager可以移动ViewPager,PagerAdapter和类的源代码到你的项目中,并添加下面的代码。
到ViewPager:
public void notifyItemChanged(Object oldItem, Object newItem) {
if (mItems != null) {
for (ItemInfo itemInfo : mItems) {
if (itemInfo.object.equals(oldItem)) {
itemInfo.object = newI
invalidate();
public void replaceFragmetns(ViewPager container, Fragment oldFragment, Fragment newFragment) {
startUpdate(container);
// remove old fragment
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
int position = getFragmentPosition(oldFragment);
while (mSavedState.size() &= position) {
mSavedState.add(null);
mSavedState.set(position, null);
mFragments.set(position, null);
mCurTransaction.remove(oldFragment);
// add new fragment
while (mFragments.size() &= position) {
mFragments.add(null);
mFragments.set(position, newFragment);
mCurTransaction.add(container.getId(), newFragment);
finishUpdate(container);
// ensure getItem returns newFragemtn after calling handleGetItemInbalidated()
handleGetItemInbalidated(container, oldFragment, newFragment);
container.notifyItemChanged(oldFragment, newFragment);
protected abstract void handleGetItemInbalidated(View container, Fragment oldFragment, Fragment newFragment);
protected abstract int getFragmentPosition(Fragment fragment);
handleGetItemInbalidated()保证的getItem的下一次调用()它返回后
返回adapter的位置。
现在,以取代电话
mAdapter.replaceFragmetns(mViewPager, oldFragment, newFragment);
如果你在一个示例项目的来源感兴趣。
伟大工程与AndroidTeam的解决方案,但是我发现我需要回去很像的能力FrgmentTransaction.addToBackStack(null)加上这只会在要被替换而不通知ViewPager。与此相结合的未成年人所提供的解决方案将使您返回到状态压倒一切的活动的onBackPressed()方法。最大的缺点是它只能回去一次一个可能导致多个后台点击
private ArrayList&Fragment& bFragments = new ArrayList&Fragment&();
private ArrayList&Integer& bPosition = new ArrayList&Integer&();
public void replaceFragmentsWithBackOut(ViewPager container, Fragment oldFragment, Fragment newFragment) {
startUpdate(container);
// remove old fragment
if (mCurTransaction == null) {
mCurTransaction = mFragmentManager.beginTransaction();
int position = getFragmentPosition(oldFragment);
while (mSavedState.size() &= position) {
mSavedState.add(null);
//Add Fragment to Back List
bFragments.add(oldFragment);
//Add Pager Position to Back List
bPosition.add(position);
mSavedState.set(position, null);
mFragments.set(position, null);
mCurTransaction.remove(oldFragment);
// add new fragment
while (mFragments.size() &= position) {
mFragments.add(null);
mFragments.set(position, newFragment);
mCurTransaction.add(container.getId(), newFragment);
finishUpdate(container);
// ensure getItem returns newFragemtn after calling handleGetItemInbalidated()
handleGetItemInvalidated(container, oldFragment, newFragment);
container.notifyItemChanged(oldFragment, newFragment);
public boolean popBackImmediate(ViewPager container){
int bFragSize = bFragments.size();
int bPosSize = bPosition.size();
if(bFragSize&0 && bPosSize&0){
if(bFragSize==bPosSize){
int last = bFragSize-1;
int position = bPosition.get(last);
//Returns Fragment Currently at this position
Fragment replacedFragment = mFragments.get(position);
Fragment originalFragment = bFragments.get(last);
this.replaceFragments(container, replacedFragment, originalFragment);
bPosition.remove(last);
bFragments.remove(last);
希望这有助于
也尽可能getFragmentPosition()去这几乎是getItem()在背面。你知道哪些去哪里,只要确保你回到正确的位置将是。下面是一个例子:
protected int getFragmentPosition(Fragment fragment) {
if(fragment.equals(originalFragment1)){
if(fragment.equals(replacementFragment1)){
if(fragment.equals(Fragment2)){
return -1;
所提出的解决方案有很多,以部分解决问题,但还有一个重要的事情,其中产生了意想不到的异常和黑色页面内容,而不是在案件内容的解决方案失踪。
问题是,类项的ID来存储缓存来。出于这个原因,你还需要重写getItemId(整数位)方法,以便它返回e。克顶级页面和页的说明100 +位置的位置。否则,创建顶层会从缓存中返回,而不是细节层次
此外,我与ViewPager和标签RadioGroup中,允许有详细页面顶级页面,同时还支持后退按钮分享这里的例子如何制表符样活性。这支持背部只有一层堆叠(项目列表-项目的详细信息),但多级回堆叠非常简单。这个例子非常有效在正常情况下,它是扔一个NullPointerException异常的情况下,当您切换到E的除外。克第二页,变更优先页的(虽然不可见),并返回到优先页。我会后一个解决这个问题的一次,我会看着办吧:
public class TabsActivity extends FragmentActivity {
public static final int PAGE_COUNT = 3;
public static final int FIRST_PAGE = 0;
public static final int SECOND_PAGE = 1;
public static final int THIRD_PAGE = 2;
* Opens a new inferior page at specified tab position and adds the current page into back
public void startPage(int position, Fragment content) {
// Replace page adapter fragment at position.
mPagerAdapter.start(position, content);
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize basic layout.
this.setContentView(R.layout.tabs_activity);
// Add tab fragments to view pager.
// Create fragments adapter.
mPagerAdapter = new PagerAdapter(pager);
ViewPager pager = (ViewPager) super.findViewById(R.id.tabs_view_pager);
pager.setAdapter(mPagerAdapter);
// Update active tab in tab bar when page changes.
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrolled(int index, float value, int nextIndex) {
// Not used.
public void onPageSelected(int index) {
RadioGroup tabs_radio_group = (RadioGroup) TabsActivity.this.findViewById(
R.id.tabs_radio_group);
switch (index) {
tabs_radio_group.check(R.id.first_radio_button);
tabs_radio_group.check(R.id.second_radio_button);
tabs_radio_group.check(R.id.third_radio_button);
public void onPageScrollStateChanged(int index) {
// Not used.
// Set "tabs" radio group on checked change listener that changes the displayed page.
RadioGroup radio_group = (RadioGroup) this.findViewById(R.id.tabs_radio_group);
radio_group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup radioGroup, int id) {
// Get view pager representing tabs.
ViewPager view_pager = (ViewPager) TabsActivity.this.findViewById(R.id.tabs_view_pager);
if (view_pager == null) {
// Change the active page.
switch (id) {
case R.id.first_radio_button: {
view_pager.setCurrentItem(FIRST_PAGE);
case R.id.second_radio_button: {
view_pager.setCurrentItem(SECOND_PAGE);
case R.id.third_radio_button: {
view_pager.setCurrentItem(THIRD_PAGE);
public void onBackPressed() {
if (!mPagerAdapter.back()) {
super.onBackPressed();
* Serves the fragments when paging.
private class PagerAdapter extends FragmentPagerAdapter {
public PagerAdapter(ViewPager container) {
super(TabsActivity.this.getSupportFragmentManager());
mContainer =
mFragmentManager = TabsActivity.this.getSupportFragmentManager();
// Prepare "empty" list of fragments.
mFragments = new ArrayList&Fragment&(){};
mBackFragments = new ArrayList&Fragment&(){};
for (int i = 0; i & PAGE_COUNT; i++) {
mFragments.add(null);
mBackFragments.add(null);
* Replaces the view pager fragment at specified position.
public void replace(int position, Fragment fragment) {
// Get currently active fragment.
Fragment old_fragment = mFragments.get(position);
if (old_fragment == null) {
// Replace the fragment using transaction and in underlaying array list.
// NOTE .addToBackStack(null) doesn't work
this.startUpdate(mContainer);
mFragmentManager.beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.remove(old_fragment).add(mContainer.getId(), fragment)
.commit();
mFragments.set(position, fragment);
this.notifyDataSetChanged();
this.finishUpdate(mContainer);
* Replaces the fragment at specified position and stores the current fragment to back stack
* so it can be restored by #back().
public void start(int position, Fragment fragment) {
// Remember current fragment.
mBackFragments.set(position, mFragments.get(position));
// Replace the displayed fragment.
this.replace(position, fragment);
* Replaces the current fragment by fragment stored in back stack. Does nothing and returns
* false if no fragment is back-stacked.
public boolean back() {
int position = mContainer.getCurrentItem();
Fragment fragment = mBackFragments.get(position);
if (fragment == null) {
// Nothing to go back.
// Restore the remembered fragment and remove it from back fragments.
this.replace(position, fragment);
mBackFragments.set(position, null);
* Returns fragment of a page at specified position.
public Fragment getItem(int position) {
// If fragment not yet initialized, create its instance.
if (mFragments.get(position) == null) {
switch (position) {
case FIRST_PAGE: {
mFragments.set(FIRST_PAGE, new DefaultFirstFragment());
case SECOND_PAGE: {
mFragments.set(SECOND_PAGE, new DefaultSecondFragment());
case THIRD_PAGE: {
mFragments.set(THIRD_PAGE, new DefaultThirdFragment());
// Return fragment instance at requested position.
return mFragments.get(position);
* Custom item ID resolution. Needed for proper page fragment caching.
* @see FragmentPagerAdapter#getItemId(int).
public long getItemId(int position) {
// Fragments from second level page hierarchy have their ID raised above 100. This is
// important to FragmentPagerAdapter because it is caching fragments to FragmentManager with
// this item ID key.
Fragment item = mFragments.get(position);
if (item != null) {
if ((item instanceof NewFirstFragment) || (item instanceof NewSecondFragment) ||
(item instanceof NewThirdFragment)) {
return 100 +
* Returns number of pages.
public int getCount() {
return mFragments.size();
public int getItemPosition(Object object)
int position = POSITION_UNCHANGED;
if ((object instanceof DefaultFirstFragment) || (object instanceof NewFirstFragment)) {
if (object.getClass() != mFragments.get(FIRST_PAGE).getClass()) {
position = POSITION_NONE;
if ((object instanceof DefaultSecondragment) || (object instanceof NewSecondFragment)) {
if (object.getClass() != mFragments.get(SECOND_PAGE).getClass()) {
position = POSITION_NONE;
if ((object instanceof DefaultThirdFragment) || (object instanceof NewThirdFragment)) {
if (object.getClass() != mFragments.get(THIRD_PAGE).getClass()) {
position = POSITION_NONE;
private ViewPager mC
private FragmentManager mFragmentM
* List of page fragments.
private List&Fragment& mF
* List of page fragments to return to in onBack();
private List&Fragment& mBackF
* Tab fragments adapter.
private PagerAdapter mPagerA
我也做了一个解决方案,这正与堆栈。这是一个更加模块化的方法,这样你们就不必在你指定每个和细节FragmentPagerAdapter。它是建立在从ActionbarSherlock派生如果我是对的谷歌演示应用程序的示例的顶部。
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
* Changed to support more Layers of fragments on each Tab.
* by sebnapi (2012)
public class TabsAdapter extends FragmentPagerAdapter
implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mC
private final TabHost mTabH
private final ViewPager mViewP
private ArrayList&String& mTabTags = new ArrayList&String&();
private HashMap&String, Stack&TabInfo&& mTabStackMap = new HashMap&String, Stack&TabInfo&&();
static final class TabInfo {
public final S
public final Class&?&
TabInfo(String _tag, Class&?& _class, Bundle _args) {
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mC
public DummyTabFactory(Context context) {
mContext =
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
public interface SaveStateBundle{
public Bundle onRemoveFragment(Bundle outState);
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext =
mTabHost = tabH
mViewPager =
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
* Add a Tab which will have Fragment Stack. Add Fragments on this Stack by using
* addFragment(FragmentManager fm, String _tag, Class&?& _class, Bundle _args)
* The Stack will hold always the default Fragment u add here.
* DON'T ADD Tabs with same tag, it's not beeing checked and results in unexpected
* beahvior.
* @param tabSpec
* @param clss
* @param args
public void addTab(TabHost.TabSpec tabSpec, Class&?& clss, Bundle args){
Stack&TabInfo& tabStack = new Stack&TabInfo&();
tabSpec.setContent(new DummyTabFactory(mContext));
mTabHost.addTab(tabSpec);
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabTags.add(tag);
// to know the position of the tab tag
tabStack.add(info);
mTabStackMap.put(tag, tabStack);
notifyDataSetChanged();
* Will add the Fragment to Tab with the Tag _tag. Provide the Class of the Fragment
* it will be instantiated by this object. Proivde _args for your Fragment.
* @param fm
* @param _tag
* @param _class
* @param _args
public void addFragment(FragmentManager fm, String _tag, Class&?& _class, Bundle _args){
TabInfo info = new TabInfo(_tag, _class, _args);
Stack&TabInfo& tabStack = mTabStackMap.get(_tag);
Fragment frag = fm.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + mTabTags.indexOf(_tag));
if(frag instanceof SaveStateBundle){
Bundle b = new Bundle();
((SaveStateBundle) frag).onRemoveFragment(b);
tabStack.peek().args =
tabStack.add(info);
FragmentTransaction ft = fm.beginTransaction();
ft.remove(frag).commit();
notifyDataSetChanged();
* Will pop the Fragment added to the Tab with the Tag _tag
* @param fm
* @param _tag
public boolean popFragment(FragmentManager fm, String _tag){
Stack&TabInfo& tabStack = mTabStackMap.get(_tag);
if(tabStack.size()&1){
tabStack.pop();
Fragment frag = fm.findFragmentByTag("android:switcher:" + mViewPager.getId() + ":" + mTabTags.indexOf(_tag));
FragmentTransaction ft = fm.beginTransaction();
ft.remove(frag).commit();
notifyDataSetChanged();
public boolean back(FragmentManager fm) {
int position = mViewPager.getCurrentItem();
return popFragment(fm, mTabTags.get(position));
public int getCount() {
return mTabStackMap.size();
public int getItemPosition(Object object) {
ArrayList&Class&?&& positionNoneHack = new ArrayList&Class&?&&();
for(Stack&TabInfo& tabStack: mTabStackMap.values()){
positionNoneHack.add(tabStack.peek().clss);
} // if the object class lies on top of our stacks, we return default
if(positionNoneHack.contains(object.getClass())){
return POSITION_UNCHANGED;
return POSITION_NONE;
public Fragment getItem(int position) {
Stack&TabInfo& tabStack = mTabStackMap.get(mTabTags.get(position));
TabInfo info = tabStack.peek();
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
public void onPageScrollStateChanged(int state) {
加入本作中你MainActivity后退按钮函数:
public void onBackPressed() {
if (!mTabsAdapter.back(getSupportFragmentManager())) {
super.onBackPressed();
如果SaveStateBundle在函数返回与您保存状态的包。通过获取束实例化之后this.getArguments()。
你可以实例化一个这样的标签:
mTabsAdapter.addTab(mTabHost.newTabSpec("firstTabTag").setIndicator("First Tab Title"),
FirstFragmentActivity.FirstFragmentFragment.class, null);
类似的作品如果u想添加一个上一个标签堆栈的顶部。
重要提示:我认为,它不会如果u希望有两个选项卡顶部类的实例工作。
我做了这个解决方案的快速在一起,所以我只能分享它没有提供任何与它的经验。
我有一个解决方案:
动态标签内
每个选项卡中的历史维护
同方向变化工作
实现这一目标的招数有以下几种:
使用notifyDataSetChanged()方法来应用
使用管理员只对后台也没有为
保持模式(堆栈)
该adapter的代码是这样的:
public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar.TabListener, ViewPager.OnPageChangeListener {
/** The sherlock fragment activity. */
private final SherlockFragmentActivity mA
/** The action bar. */
private final ActionBar mActionB
/** The pager. */
private final ViewPager mP
/** The tabs. */
private List&TabInfo& mTabs = new LinkedList&TabInfo&();
/** The total number of tabs. */
private int TOTAL_TABS;
private Map&Integer, Stack&TabInfo&& history = new HashMap&Integer, Stack&TabInfo&&();
* Creates a new instance.
* @param activity the activity
* @param pager the pager
public TabsAdapter(SherlockFragmentActivity activity, ViewPager pager) {
super(activity.getSupportFragmentManager());
activity.getSupportFragmentManager();
this.mActivity =
this.mActionBar = activity.getSupportActionBar();
this.mPager =
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
* Adds the tab.
* @param image
* @param fragmentClass the class
* @param args
the arguments
public void addTab(final Drawable image, final Class fragmentClass, final Bundle args) {
final TabInfo tabInfo = new TabInfo(fragmentClass, args);
final ActionBar.Tab tab = mActionBar.newTab();
tab.setTabListener(this);
tab.setTag(tabInfo);
tab.setIcon(image);
mTabs.add(tabInfo);
mActionBar.addTab(tab);
notifyDataSetChanged();
public Fragment getItem(final int position) {
final TabInfo tabInfo = mTabs.get(position);
return Fragment.instantiate(mActivity, tabInfo.fragmentClass.getName(), tabInfo.args);
public int getItemPosition(final Object object) {
/* Get the current position. */
int position = mActionBar.getSelectedTab().getPosition();
/* The default value. */
int pos = POSITION_NONE;
if (history.get(position).isEmpty()) {
return POSITION_NONE;
/* Checks if the object exists in current history. */
for (Stack&TabInfo& stack : history.values()) {
TabInfo c = stack.peek();
if (c.fragmentClass.getName().equals(object.getClass().getName())) {
pos = POSITION_UNCHANGED;
public int getCount() {
return mTabs.size();
public void onPageScrollStateChanged(int arg0) {
public void onPageScrolled(int arg0, float arg1, int arg2) {
public void onPageSelected(int position) {
mActionBar.setSelectedNavigationItem(position);
public void onTabSelected(final ActionBar.Tab tab, final FragmentTransaction ft) {
TabInfo tabInfo = (TabInfo) tab.getTag();
for (int i = 0; i & mTabs.size(); i++) {
if (mTabs.get(i).equals(tabInfo)) {
mPager.setCurrentItem(i);
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
public void replace(final int position, final Class fragmentClass, final Bundle args) {
/* Save the fragment to the history. */
mActivity.getSupportFragmentManager().beginTransaction().addToBackStack(null).commit();
/* Update the tabs. */
updateTabs(new TabInfo(fragmentClass, args), position);
/* Updates the history. */
history.get(position).push(new TabInfo(mTabs.get(position).fragmentClass, mTabs.get(position).args));
notifyDataSetChanged();
* Updates the tabs.
* @param tabInfo
the new tab info
* @param position
the position
private void updateTabs(final TabInfo tabInfo, final int position) {
mTabs.remove(position);
mTabs.add(position, tabInfo);
mActionBar.getTabAt(position).setTag(tabInfo);
* Creates the history using the current state.
public void createHistory() {
int position = 0;
TOTAL_TABS = mTabs.size();
for (TabInfo mTab : mTabs) {
if (history.get(position) == null) {
history.put(position, new Stack&TabInfo&());
history.get(position).push(new TabInfo(mTab.fragmentClass, mTab.args));
position++;
* Called on back
public void back() {
int position = mActionBar.getSelectedTab().getPosition();
if (!historyIsEmpty(position)) {
/* In case there is not any other item in the history, then finalize the activity. */
if (isLastItemInHistory(position)) {
mActivity.finish();
final TabInfo currentTabInfo = getPrevious(position);
mTabs.clear();
for (int i = 0; i & TOTAL_TABS; i++) {
if (i == position) {
mTabs.add(new TabInfo(currentTabInfo.fragmentClass, currentTabInfo.args));
TabInfo otherTabInfo = history.get(i).peek();
mTabs.add(new TabInfo(otherTabInfo.fragmentClass, otherTabInfo.args));
mActionBar.selectTab(mActionBar.getTabAt(position));
notifyDataSetChanged();
* Returns if the history is empty.
* @param position
the position
* @return the flag if empty
private boolean historyIsEmpty(final int position) {
return history == null || history.isEmpty() || history.get(position).isEmpty();
private boolean isLastItemInHistory(final int position) {
return history.get(position).size() == 1;
* Returns the previous state by the position provided.
* @param position
the position
* @return the tab info
private TabInfo getPrevious(final int position) {
TabInfo currentTabInfo = history.get(position).pop();
if (!history.get(position).isEmpty()) {
currentTabInfo = history.get(position).peek();
return currentTabI
/** The tab info class */
private static class TabInfo {
/** The fragment class. */
public Class fragmentC
/** The args.*/
* Creates a new instance.
* @param fragmentClass
the fragment class
* @param args
public TabInfo(Class fragmentClass, Bundle args) {
this.fragmentClass = fragmentC
this.args =
public boolean equals(final Object o) {
return this.fragmentClass.getName().equals(o.getClass().getName());
public int hashCode() {
return fragmentClass.getName() != null ? fragmentClass.getName().hashCode() : 0;
public String toString() {
return "TabInfo{" +
"fragmentClass=" + fragmentClass +
最先添加的所有标签,我们需要调用createHistory()来创建初始历史
public void createHistory() {
int position = 0;
TOTAL_TABS = mTabs.size();
for (TabInfo mTab : mTabs) {
if (history.get(position) == null) {
history.put(position, new Stack&TabInfo&());
history.get(position).push(new TabInfo(mTab.fragmentClass, mTab.args));
position++;
每次你要替换一个给你调用一个特定的选项卡:
更换(最终诠释的位置,最终的决赛绑定类参数)
/* Save the fragment to the history. */
mActivity.getSupportFragmentManager().beginTransaction().addToBackStack(null).commit();
/* Update the tabs. */
updateTabs(new TabInfo(fragmentClass, args), position);
/* Updates the history. */
history.get(position).push(new TabInfo(mTabs.get(position).fragmentClass, mTabs.get(position).args));
notifyDataSetChanged();
上回压你需要调用后面()方法:
public void back() {
int position = mActionBar.getSelectedTab().getPosition();
if (!historyIsEmpty(position)) {
/* In case there is not any other item in the history, then finalize the activity. */
if (isLastItemInHistory(position)) {
mActivity.finish();
final TabInfo currentTabInfo = getPrevious(position);
mTabs.clear();
for (int i = 0; i & TOTAL_TABS; i++) {
if (i == position) {
mTabs.add(new TabInfo(currentTabInfo.fragmentClass, currentTabInfo.args));
TabInfo otherTabInfo = history.get(i).peek();
mTabs.add(new TabInfo(otherTabInfo.fragmentClass, otherTabInfo.args));
mActionBar.selectTab(mActionBar.getTabAt(position));
notifyDataSetChanged();
该解决方案可与福尔摩斯行动起来吧,与轻扫手势。
我已经实现了,使用@mdelolmo的回答,以取代Fragment与另一个在一个页面中ViewPager并返回从第二Fragment到优先个。
你可以看到我的代码在这里。
这里是我的比较简单的解决这个问题。该键在该溶液是FragmentStatePagerAdapter而不是FragmentPagerAdapter作为将删除你而后来仍然保留它们的实例。第二个是POSITION_NONE在getItem()时。我'一个简单的列表,以保持我的我的轨道是,以取代在一次与一个新的列表的完整列表,但下面可以很容易地修改,以取代个人
public class MyFragmentAdapter extends FragmentStatePagerAdapter {
private List&Fragment& fragmentList = new ArrayList&Fragment&();
private List&String& tabTitleList = new ArrayList&String&();
public MyFragmentAdapter(FragmentManager fm) {
super(fm);
public void addFragments(List&Fragment& fragments, List&String& titles) {
fragmentList.clear();
tabTitleList.clear();
fragmentList.addAll(fragments);
tabTitleList.addAll(titles);
notifyDataSetChanged();
public int getItemPosition(Object object) {
if (fragmentList.contains(object)) {
return POSITION_UNCHANGED;
return POSITION_NONE;
public Fragment getItem(int item) {
if (item &= fragmentList.size()) {
return fragmentList.get(item);
public int getCount() {
return fragmentList.size();
public CharSequence getPageTitle(int position) {
return tabTitleList.get(position);
本文标题 :替换片段里面ViewPager
本文地址 :CodeGo.net/365517/
Copyright (C) 2017 CodeGo.net}

我要回帖

更多关于 tablayout viewpager 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信