0


我一直在开发一个小的Android应用程序,但我面临一个我很难解决的错误。指定正确的android片段旋转

由于我使用的是BottomNavigationView我必须初始化我的家庭片段是这样的:

@Override 
protected void onStart(){ 
    super.onStart(); 
    FragmentTransaction f = fm.beginTransaction(); 
    f.replace(R.id.content, homeFragment).commit(); 
} 

替换发生在此的FrameLayout:

<FrameLayout 
    android:id="@+id/content" 
    android:layout_width="0dp" 
    android:layout_height="0dp" 
    android:visibility="visible" 
    app:layout_constraintBottom_toTopOf="@+id/navigation" 
    app:layout_constraintEnd_toEndOf="parent" 
    app:layout_constraintHorizontal_bias="0.5" 
    app:layout_constraintStart_toStartOf="parent" 
    app:layout_constraintTop_toTopOf="parent" 
    app:layout_constraintVertical_bias="1.0" /> 

然而,这引起了一个小错误:如果我旋转设备片段设置回我homeFragment,无论当前。
既然不能直接叫我的

public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
// 
} 

我tryed一些周转:

  • 我使用布尔isFragmentInitialized
  • 我tryed下放onNavigation功能到外部tryed私人setFragment函数检查所选菜单项并应用相应的片段
  • 我试过直接用homeFragment开始,而不是用我使用的线性视图

但theese解决方案带来了没有运气:你打开屏幕,并选择回家
别人只会导致与我的标准初始化相同的情况下
最后一个崩溃后。

回答

1

也许这样做会导致您的代码运行仅在第一次用户导航到你的Activity是从onStart()移动你的代码onCreate(),敷的if声明,检查里面是否savedInstanceState为空(最简单的事情这只会在活动第一次启动时才为真)。

@Override 
protected void onCreate(Bundle savedInstanceState){ 
    super.onCreate(); 
    // the rest of your onCreate() etc... 

    if (savedInstanceState == null){ 
     FragmentTransaction f = fm.beginTransaction(); 
     f.replace(R.id.content, homeFragment).commit(); 
    } 
} 

您可以使用这种技术要运行仅在第一次您的任何活动开始了,不仅仅是FragmentTransaction秒。虽然片段是这个技巧的一个非常常见的用例。

+0

它很有效! 感谢您的快速和有益的答案! – Tails128

0

你可以做到这一点的一种方法是创建一个变量来存储一个片段标签,在处理你的底部导航的开关箱中,你可以在该变量中保存适当的标签。然后执行onSaveInstanceState函数并将该标签写入您的境外。最后,在onCreate中监听保存的实例状态并启动相应的片段。像这样:

String fragmentTag; 
String FRAGMENT-TAG-KEY = "fragment-tag"; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // recovering the instance state 
    if (savedInstanceState != null) { 
     String fragmentTag = savedInstanceState.getString("FRAGMENT-TAG-KEY"); 
     switch (fragmentTag){ 
      case "FragmentA": { 
       //launch this fragment. 
       break; 
      } 
      case "FragmentB": { 
       //launch this fragment. 
       break; 
      } 
     } 
    } 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    outState.putString(FRAGMENT-TAG-KEY, fragmentTag); 
    super.onSaveInstanceState(outState); 
} 


bottomNavigationView.setOnNavigationItemSelectedListener(
    new BottomNavigationView.OnNavigationItemSelectedListener() { 
     @Override 
     public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
      switch (item.getItemId()) { 
       case R.id.action_home: { 
        fragmentTag = "FragmentA"; 
       } 

       case R.id.action_fragmentb: { 
        fragmentTag = "FragmentA"; 
       } 
      } 
      return true; 
     } 
    }); 

如果是这种情况,该特定的片段需要存储数据,您可以将其存储在本地并重新加载它。否则,您可能需要将数据发送回活动,然后将其传递到您的片段中。可能会出现这种情况,您可以存储片段的实例并在片段中实现outstate,然后在onActivityCreated的片段中可以恢复实例状态。我不确定代码的其余部分是什么样子,所以我只能推测如果存储碎片数据的话可能会如何存储。