2012-04-04 240 views
0

我使用的是ViewPager有4页,和我在寻找一种有效的方式来代替片段之间/开关每一页。在ViewPager替换片段使用FragmentPagerAdapter

这是我试图创建交互模式:

  1. 用户按下目前持有碎片A
  2. 片段A被换出一些新的B片段在页面上的一个按钮
  3. 用户确实在B片段一些工作,并随后按下时,他/她完成
  4. 片段B被移除的按钮,并且由片段A(原片段)
取代

我发现了一种方法来做到这一点,但它似乎有重大缺陷。该解决方案涉及除去原片段,然后重写getItemPosition(基本上是在此描述related question法):

//An array to keep track of the currently visible fragment in each page 
private final Fragment[] activeFragments= new Fragment[4]; 

public void openFragmentB(ViewPager pager, int position) { 

    startUpdate(pager); 

    //Remove the original fragment 
    FragmentTransaction transaction = fragmentManager.beginTransaction(); 
    transaction.remove(activeFragments[position]); 
    transaction.commit(); 

    //Create a new tile search fragment to replace the original fragment 
    activeFragments[position] = FragmentB.newInstance(); 
    pageStates[position] = PageState.STATE_B; 

    finishUpdate(pager); 
    notifyDataSetChanged(); 
} 

@Override 
public int getItemPosition(Object object) { 

    //If the main fragment is not active, return POSITION_NONE 
    if(object instanceof FragmentA) { 
     FragmentA a = (FragmentA) object; 
     if(pageStates[a.getPosition()] != PageState.STATE_A) { 
      return POSITION_NONE; 
     } 
    } 

    //If the secondary fragment is not active, return POSITION_NONE 
    if(object instanceof FragmentB) { 
     FragmentB b = (FragmentB) object; 
     if(pageStates[b.getPosition()] != PageState.STATE_B) { 
      return POSITION_NONE; 
     } 
    } 

    return POSITION_UNCHANGED; 
} 

这种方法有效,但具有不期望的副作用。删除片段并将其置于POSITION_NONE位置会导致片段被破坏。所以当用户完成使用FragmentB时,我需要创建一个FragmentA的新实例,而不是重用原始片段。寻呼机中的主要片段(本例中为FragmentA)将包含相对较大的数据库支持列表,因此我希望尽可能避免重新创建它们。

基本上我只是想继续引用我的4个主要碎片和交换他们进出的网页,而无需每次都重新创建它们。有任何想法吗?

+0

'Fragments'也'Views',你可以用'Fragments'你需要换,就用'setVisibility()'来删除和添加他们创造一个布局。 – adneal 2012-04-04 06:29:05

回答

1

避免重新创建碎片的一种简单方法是将它们作为成员变量保存在您的活动中。无论如何,我都会配合onRetainCustomNonConfigurationInstance()来执行此操作,以便在配置更改(主要是屏幕旋转)期间保留我的片段。由于onRetainCustomNonConfigurationInstance只返回一个对象,因此我将片段保留在'retainer'对象中。

在你的情况,而不是调用Fragment.newInstance()所有的时间,只是检查,看是否包含在固定物体的片段是创建一个新的前空。如果它不是null,则只需重新使用先前的实例。这种检查应该发生在ViewPager适配器的getItem(int)方法中。

实际上,这样做基本上意味着您正在处理是否在调用getItem时回收碎片,并覆盖getItemPosition(Object)方法以在相关Segmentation时始终返回POSITION_NONE。

1

FragmentPagerAdapter提供了一个名为getItemId覆写投放方法,这将帮助你在这里。

如果您分配您的收藏在一个独特的长期价值,以每个片段,并返回,在这种方法中,它会迫使ViewPager当它注意到了ID已更改为重新加载页面。

比从未更好的迟到,我希望这有助于有人在那里!