【问题标题】:Android tabs fragment crashes when changing to landscape更改为横向时,Android选项卡片段崩溃
【发布时间】:2014-03-10 20:29:21
【问题描述】:

我有一个使用片段的 3 个选项卡的活动,它在纵向模式下工作正常,但是,当我将其更改为横向时,它会崩溃。这是代码:

public class MainMenuActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_menu);

        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

        String label1 = getResources().getString(R.string.userMainTab);
        Tab tab = actionBar.newTab();
        tab.setText(label1);
        TabListener<UserTabActivity> tl = new TabListener<UserTabActivity>(this, label1, UserTabActivity.class);
        tab.setTabListener(tl);
        actionBar.addTab(tab);

        String label2 = getResources().getString(R.string.credentialGroupMainTab);
        Tab tab2 = actionBar.newTab();
        tab2.setText(label2);
        TabListener<CredentialGroupActivity> tl2 = new TabListener<CredentialGroupActivity>(this, label2, CredentialGroupActivity.class);
        tab2.setTabListener(tl2);
        actionBar.addTab(tab2);

        String label3 = getResources().getString(R.string.credentialTabHeader);
        Tab tab3 = actionBar.newTab();
        tab3.setText(label3);
        TabListener<CredentialTabActivity> tl3 = new TabListener<CredentialTabActivity>(this, label2, CredentialTabActivity.class);
        tab3.setTabListener(tl3);
        actionBar.addTab(tab3);     

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }   

    public static class TabListener<T extends Fragment> implements ActionBar.TabListener{

        private Fragment mFragment;
        private final Activity mActivity;
        private final String mTag;
        private final Class<T> mClass;

        public TabListener(Activity activity, String tag, Class<T> clz){
            mActivity = activity;
            mTag = tag;
            mClass = clz;

            mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
            if(mFragment != null && !mFragment.isDetached()){
                FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
                ft.detach(mFragment);
                ft.commit();
            }
        }

        @Override
        public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
            // TODO Auto-generated method stub
            if(mFragment == null){
                mFragment = Fragment.instantiate(mActivity, mClass.getName());
                arg1.add(android.R.id.content, mFragment, mTag);
            } else{
                arg1.attach(mFragment);
            }
        }

        @Override
        public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
            // TODO Auto-generated method stub
            if(mFragment != null){
                arg1.detach(mFragment);
            }
        }

    }

}

你能告诉我为什么不工作吗?错误是:

java.lang.RuntimeException: Unable to destroy activity{ACTIVITY_NAME} : java.lang.NullPointerException

我注意到它失败了,直到我单击任何选项卡,然后尝试将其更改为横向,但我无法在代码中识别正在发生的事情,以及当我更改视图时,它会丢失它所在的选项卡。

提前致谢!

编辑

为了在更改方向后保留选定的标签,我最终这样做了,感谢 Nathaniel Waggoner 和 karthikk 提出的建议:

protected void onSaveInstanceState(Bundle outState) {
    // TODO Auto-generated method stub
    super.onSaveInstanceState(outState);

    outState.putInt("tabState", actionBar.getSelectedTab().getPosition());
}

//In the onCreate method
    if(savedInstanceState != null ){
        actionBar.selectTab(actionBar.getTabAt(savedInstanceState.getInt("tabState")));
    }

谢谢!!

【问题讨论】:

标签: android tabs orientation fragment landscape


【解决方案1】:

要保留选项卡选择,

  1. 必须优先存储或
  2. 覆盖 onSaveInstanceState() 并保存 TAB_SELECTION。在配置更改时,您的活动将通过 onRestoreInstanceState() API 将先前的状态作为 Bundle 提供。

我建议参考http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)了解更多信息。

【讨论】:

    【解决方案2】:

    您是否在片段中覆盖 onDestroy?您显示的 NPE 是我在选项卡中使用的片段中覆盖 OnDestroy 时看到的症状。如果你是,我会删除那个覆盖,看看这是否能解决这个问题。

    【讨论】:

    • 我在每个片段中都有 onDestroy 方法。我评论了覆盖,它现在可以工作了!谢谢!但是,我有一个问题;我正在使用 onDestroy 方法关闭数据库连接,我认为这是最好的方法,你知道另一种方法吗?谢谢!
    • 将它放在 onDetach 或 onDestroyView 中,只需执行其中一个 @Override 即可。
    • 太棒了!谢谢!再一次,我已经完成了......每次我改变方向时,我都会失去对选定选项卡的关注,它会回到第一个,可能是什么问题?谢谢!
    • 你需要调用 actionBar.selectTab(mainTab);在您的活动生命周期中 - 您可以覆盖 onOrientationChange 或其他一些生命周期方法。您需要注意片段生命周期的一些复杂问题......即片段在内存中的徘徊方式。
    • 如果我使用 onDetach 或 onDestroyView,我仍然会收到 NPE 错误,如果我不使用它们,应用程序可以正常工作,但我想知道为什么会这样,此外,我想确保关闭光标和数据库。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多