2014-02-16 133 views
5

我有3个片段的活动和寻呼机。我使用标签进行切换。 当我点击某个按钮时,我想用新的替换fragment0。 仅当fragment0具有空布局时才起作用。如果我设置在fragment0布局一些内容(必须有列表视图)抛出异常:布局不为空时得到“java.lang.IllegalStateException:片段已激活”

java.lang.IllegalStateException: Fragment already active 
    at android.support.v4.app.Fragment.setInitialSavedState(Fragment.java:503) 
    at android.support.v4.app.FragmentStatePagerAdapter.instantiateItem(FragmentStatePagerAdapter.java:110) 
    at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:649) 

我用以下布局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:orientation="vertical" 
      android:id="@+id/all_exp_frag" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent"> 

<ListView 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:id="@+id/all_expenses"/> 

</LinearLayout> 

活动:

public class Activity extends FragmentActivity { 

    private List<Fragment> fragments; 
    private MyPagerAdapter pagerAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     fragments = asList(new Fragment0(), new Fragment1(), new Fragment2()); 
     // initialize pager, etc. 
     pagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), pager); 
    } 

    // handle add new fragment button 
    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     pagerAdapter.replaceCurrentFragment(new Fragment3()); 
    } 

    public class MyPagerAdapter extends FragmentStatePagerAdapter { 

     final ViewPager pager; 

     public MyPagerAdapter(FragmentManager fm, ViewPager pager) { 
      super(fm); 
      this.pager = pager; 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      return fragments.get(position).getFragmentTitle(); 
     } 

     @Override 
     public int getCount() { 
      return fragments.size(); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      return fragments.get(position); 
     } 

     @Override 
     public int getItemPosition(Object object) { 
      if (object instanceof ExpensesFragment) { 
       return POSITION_NONE; 
      } 
      return POSITION_UNCHANGED; 
     } 

     public void replaceCurrentFragment(BaseFragment fragment) { 
      final int currentPosition = pager.getCurrentItem(); 
      final BaseFragment old_fragment = fragments.get(currentPosition); 
      if (old_fragment == null) { 
       return; 
      } 
      this.startUpdate(pager); 
      getSupportFragmentManager() 
        .beginTransaction() 
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) 
        .remove(old_fragment) 
        .add(pager.getId(), fragment) 
        .commitAllowingStateLoss(); 
      fragments.set(currentPosition, fragment); 
      this.finishUpdate(pager); 
      this.notifyDataSetChanged(); //IN THIS LINE EXCEPTION IS THROWN WHEN LAYOUT IS NOT EMPTY (contains listview). IF EMPTY - IT WORKS FINE. 
      listener.onPageSelected(0); 
     } 

    } 
} 

应用程序抛出在线例外

this.notifyDataSetChanged();

如果布局不为空。

我无法找到解决方案如何避免此异常并正确地替换片段。

EDITED

https://android.googlesource.com/platform/frameworks/support/+/jb-mr1-dev/v4/java/android/support/v4/app/Fragment.java

为我检查片段类包含以下方法:

public void setArguments(Bundle args) { 
    if (mIndex >= 0) { 
     throw new IllegalStateException("Fragment already active"); 
    } 
    mArguments = args; 
} 

也许我加入碎片的方式是不正确的..

+0

难道你长了针对此问题的解决方案..请更新的答案? – CoDe

回答

3

它只是添加片段的错误逻辑。良好的工作解决方案可以在这里找到:片段correct answer

+1

如果确实是一个重复的问题,那么将其标记为重复的解决方案,然后转到该路线。否则,举个例子,请不要链接到其他页面。这就是事情在这里变得混乱的原因。 :) –

1

检查是否已经添加或不使用片段#isAdded()方法。然后更换或添加相应的片段:

让我们假设你的片段被称为fragment

// Fragment object 
Fragment fragment; 

// Check to see if it's added or not like this 
if (!fragment.isAdded()) { 
    // Things you could do here: 
    // -- Set argument 
    // -- Begin a transaction 
    // -- etc... 
} 
相关问题