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的片段中可以恢復實例狀態。我不確定代碼的其餘部分是什麼樣子,所以我只能推測如果存儲碎片數據的話可能會如何存儲。