处理片段和视图分页器:无法更改片段的标记和递归到executePendingTransactions的条目

时间:2013-02-25 21:29:30

标签: android android-fragments android-viewpager

首先,我知道这些主题已经在stackoverflow上创建了很多时间,但我没有找到解决问题的方法。其次,我是法国人,所以我的英语不完美,对不起,请告诉我,如果你不明白的话。为了完成这个介绍,这是我第一次处理片段,所以,抱歉,如果有一些我不太了解的东西!

我有三个按钮,允许在三个片段之间切换。 在其中一个片段中,我有一个带有两个片段的视图寻呼机。目前,每个片段(有5个),只包含一个TextView。 我正在使用最新版本的android-support-v4(我已经在stackoverflow中阅读了很多主题,说最新版本的支持解决了我的“递归进入executePendingTransactions”错误。)

我的两个问题:

  • 当我在一个按钮中单击两次时,我有一个IllegaleStateException“无法更改片段的标记”。我能够通过在onButtonSelected方法上创建一个新片段来解决这个问题,但是我不希望每次都重新创建片段,出于内存原因和功能原因:片段必须保持她的状态。这个问题不是我的主要问题,事实上,我知道当用户已经处于碎片状态时禁用按钮是可能的,但是当没有进行此管理时会出现异常,不是吗?

  • 当我从带有视图寻呼机的片段出去,然后我回到这个片段时,我有一个IllegalStateException“递归进入executePendingTransactions”。我可以通过在处理程序上设置我的适配器来解决这个问题,或者使用FragmentStatePagerAdapter而不是FragmentPageAdapter(请参阅Display fragment viewpager within a fragment),但即使我的应用程序没有崩溃,当我使用视图寻呼机返回我的片段时,查看传呼机已消失!

你能帮助我吗?

Java源代码如下,我认为布局源代码是无用的。

MainActivity:

public class MainActivity extends SherlockFragmentActivity{

private SherlockFragment fragmentOne, fragmentTwo, fragmentThree;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

//      this.fragmentOne = new fragmentOne();
//      this.fragmentTwo = new fragmentTwo();
//      this.fragmentThree = new fragmentThree();
// Call new or instanciate ? What's the correct way ?

    this.fragmentOne = (SherlockFragment) SherlockFragment.instantiate(this, FragmentOne.class.getName());
    this.fragmentTwo = (SherlockFragment) SherlockFragment.instantiate(this, FragmentTwo.class.getName());
    this.fragmentThree = (SherlockFragment) SherlockFragment.instantiate(this, FragmentThree.class.getName());

    // Add fragment
    FragmentTransaction transaction = (
        this.getSupportFragmentManager().beginTransaction()
    );      
    transaction.add(
        R.id.tab_fragment,
        this.fragmentOne,
        this.fragmentOne.toString()
    );
    transaction.commit();

}

public void onButtonSelected(View v){

    switch (v.getId()){

        case R.id.button_one_tab:{
            showFragment(this.fragmentThree);
            break;
        }
        case R.id.button_two_tab:{
            showFragment(this.fragmentOne);
            break;
        }
        case R.id.button_three_tab:{
            showFragment(this.fragmentTwo);
            break;
        }
        default:{
            break;
        }

    }

}

public void showFragment(SherlockFragment fragmentToShow){

    FragmentTransaction transaction = (
        this.getSupportFragmentManager().beginTransaction()
    );

    transaction.replace(R.id.tab_fragment, fragmentToShow, fragmentToShow.toString());
    transaction.commit();

}

}

片段2和3仅对仅包含TextView的布局进行扩充。 片段一(注意我使用的是DirectionalViewPager - 一个lib - 而不是一个ViewPager):

public class FragmentOne extends SherlockFragment{

private FragmentOneAdapter fragmentOneAdapter;

@Override
public void onActivityCreated(Bundle savedInstanceState) {

    super.onActivityCreated(savedInstanceState);

    // Set up the pager
    final DirectionalViewPager pager = (DirectionalViewPager)getActivity().findViewById(R.id.pager);
    if (this.fragmentOneAdapter== null){
        this.fragmentOneAdapter= new FragmentOneAdapter (getActivity().getSupportFragmentManager());
    }
    pager.setAdapter(fragmentOneAdapter);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_landing_page, container, false);
}

FragmentOneAdapter:

public class FragmentOneAdapter extends FragmentPagerAdapter{

private ArrayList<SherlockFragment> fragmentsList;

public FragmentOneAdapter(FragmentManager fragmentManager) {

    super(fragmentManager);

    SherlockFragment fragmentFour = new FragmentFour();
    SherlockFragment fragmentFive = new FragmentFive();

    this.fragmentsList = new ArrayList<SherlockFragment>();
    this.fragmentsList.add(fragmentFour);
    this.fragmentsList.add(fragmentFive);

}

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

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

}

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

我已经解决了我的问题!

我只是将getSupportFragmentManager()上的FragmentOne替换为getChildFragmentManager()。然后,我通过每次创建一个新的片段实例来编辑我的onButtonSelected方法,而不是使用我的三个不同的实例(如果我不这样做,我有一个例外:java.lang.IllegalStateException: Activity has been destroyed) 。

此解决方案仍然存在问题:每次我在fragmentOnefragmentTwofragmentThree之间切换时,我都会丢失每个片段的状态。你有解决方案吗?