首页 文章

当方向改变时,如何保留导航抽屉选择的片段?使用Xamarin

提问于
浏览
0

我正在使用C#/ Xamarin中的Android应用程序 .

我只使用一个活动,有12个碎片 . 我在主要活动中有一个导航抽屉,其中选择加载12个片段中的一个 . 这是我的MainActivity类的开始 . 如您所见,OnCreate加载savedInstanceState,仅在savedInstanceState为null时才创建片段 .

public class MainActivity : AppCompatActivity
{
    private DrawerLayout drawerLayout;
    private SupportFragment currentFragment = new Weight_Fragment();
    private Weight_Fragment mWeightFragment;
    private Distance_Fragment mDistanceFragment;
    private Volume_Fragment mVolumeFragment;
    private Help_Fragment mHelpFragment;
    private Temperature_Fragment mTempFragment;
    private Time_Fragment mTimeFragment;
    private Data_Fragment mDataFragment;
    private Pressure_Fragment mPressureFragment;
    private Energy_Fragment mEnergyFragment;
    private Force_Fragment mForceFragment;

    protected override void OnCreate(Bundle savedInstanceState)
    {           
        base.OnCreate(savedInstanceState);

        // Create UI
        SetContentView(Resource.Layout.Main);
        drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);

        //Init Fragments
        if (savedInstanceState == null)
        {
            mWeightFragment = new Weight_Fragment();
            mDistanceFragment = new Distance_Fragment();
            mVolumeFragment = new Volume_Fragment();
            mHelpFragment = new Help_Fragment();
            mTempFragment = new Temperature_Fragment();
            mTimeFragment = new Time_Fragment();
            mDataFragment = new Data_Fragment();
            mPressureFragment = new Pressure_Fragment();
            mEnergyFragment = new Energy_Fragment();
            mForceFragment = new Force_Fragment();

            //Add Fragments to Manager
            var trans = SupportFragmentManager.BeginTransaction();
            trans.Add(Resource.Id.fragmentContainer, mHelpFragment, "Help");
            trans.Hide(mHelpFragment);
            trans.Add(Resource.Id.fragmentContainer, mDistanceFragment, "Distance");
            trans.Hide(mDistanceFragment);
            trans.Add(Resource.Id.fragmentContainer, mVolumeFragment, "Volume");
            trans.Hide(mVolumeFragment);
            trans.Add(Resource.Id.fragmentContainer, mTempFragment, "Temperature");
            trans.Hide(mTempFragment);
            trans.Add(Resource.Id.fragmentContainer, mPressureFragment, "Pressure");
            trans.Hide(mPressureFragment);
            trans.Add(Resource.Id.fragmentContainer, mEnergyFragment, "Energy");
            trans.Hide(mEnergyFragment);
            trans.Add(Resource.Id.fragmentContainer, mForceFragment, "Force");
            trans.Hide(mForceFragment);
            trans.Add(Resource.Id.fragmentContainer, mTimeFragment, "Time");
            trans.Hide(mTimeFragment);
            trans.Add(Resource.Id.fragmentContainer, mDataFragment, "Data Storage");
            trans.Hide(mDataFragment);
            trans.Add(Resource.Id.fragmentContainer, mWeightFragment, "Weight");
            trans.Commit();
            currentFragment = mWeightFragment;
        }

导航抽屉在片段之间切换,如下所示:

void NavigationView_NavigationItemSelected(object sender, NavigationView.NavigationItemSelectedEventArgs e)
    {
        Toolbar toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);

        switch (e.MenuItem.ItemId)
        {
            case (Resource.Id.nav_weight):
                toolbar.Title = "Weight";
                ShowFragment(mWeightFragment);
                break;
            case (Resource.Id.nav_distance):
                toolbar.Title = "Distance";
                ShowFragment(mDistanceFragment);
                break;
            case (Resource.Id.nav_volume):
                toolbar.Title = "Volume";
                ShowFragment(mVolumeFragment);
                break;
            case (Resource.Id.nav_temperature):
                toolbar.Title = "Temperature";
                ShowFragment(mTempFragment);
                break;
            case (Resource.Id.nav_pressure):
                toolbar.Title = "Pressure";
                ShowFragment(mPressureFragment);
                break;
            case (Resource.Id.nav_energy):
                toolbar.Title = "Energy";
                ShowFragment(mEnergyFragment);
                break;
            case (Resource.Id.nav_force):
                toolbar.Title = "Force";
                ShowFragment(mForceFragment);
                break;
            case (Resource.Id.nav_time):
                toolbar.Title = "Time";
                ShowFragment(mTimeFragment);
                break;
            case (Resource.Id.nav_data):
                toolbar.Title = "Data Storage";
                ShowFragment(mDataFragment);
                break;
            case (Resource.Id.help):
                toolbar.Title = "Help";
                ShowFragment(mHelpFragment);
                break; 
        }

我对OnSaveInstanceState的重写非常简单:

public override void OnSaveInstanceState(Bundle outState, PersistableBundle outPersistentState)
    {
        base.OnSaveInstanceState(outState, outPersistentState);
    }

当设备方向更改时,MainActivity将重新启动,从而重新创建所有片段,从而显示mWeightFragment,因为它是创建片段时唯一未隐藏的片段 .

我有纵向和横向方向的单独布局,因此我需要在方向更改时以某种方式更新片段,因此将显示相应的布局 . 我还需要应用程序保持相同的片段,而不是每次方向更改时跳回到mWeightFragment .

在使用OnSaveInstanceState并且仅在第一次创建活动时创建片段后,我收到以下错误:

未处理的异常:Java.Lang.NullPointerException:尝试在空对象引用上写入字段'int android.support.v4.app.Fragment.mNextAnim'

但只有在改变方向后 . 如果我只是选择一个不同的片段,然后改变方向,然后改变方向,它工作正常,并保持在我想要的同一片段,但一旦我尝试再次更改片段,我得到该错误 .

1 回答

  • 0

    在你的清单中确保你有:

    <activity android:configChanges="orientation|screenSize|keyboardHidden" />
    

    还要确保你超越了OnSavedInstanceState:

    protected override void OnSaveInstanceState(Bundle outState)
        {
        }
    

    在类文件中

相关问题