使用replace()后如何保存片段的实例状态?

时间:2019-04-10 10:28:35

标签: android android-fragments kotlin

“我的活动”有3个子片段-一次仅显示1个。我正在使用BottomNavigationView在子片段之间切换。通过supportFragmentManager.beginTransaction().replace()创建活动时,显示的初始子片段GameFragment()膨胀,它替换了XML中的片段容器。

首先,让我向您展示我进入活动的整个生命周期,在replace()上切换片段,然后在replace()上切换回初始片段。这些日志语句仅与活动和片段A(未显示片段B和C)相关。

onCreate (Activity)
onAttach (Fragment A)
onCreate (Fragment A)
onCreateView (Fragment A)
onActivityCreated (Fragment A)

.replace()片段A和片段B

onPause (Fragment A)
onStop (Fragment A)

.replace()片段B和片段A

onAttach (Fragment A)
onCreate (Fragment A)
onCreateView (Fragment A)
onActivityCreated (Fragment A)

为了在使用replace()切换片段时保留片段状态,我尝试了以下两种方法都失败了。

  1. onDestroyView()中的片段中更改成员变量的值,然后在onActivityCreated()中访问它

  2. getArguments()中添加到onDestroyView(),并在onActivityCreated()中访问。

    class GameFragment : Fragment(), View.OnClickListener {
    
        var truthisvisible = "string"
    
        override fun onDestroyView() {
            super.onDestroyView()
            truthisvisible = "stringafter"
            arguments?.putString("success", "success")
    
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            return inflater.inflate(R.layout.fragment_game, container, false)
        }
    
        override fun onActivityCreated(savedInstanceState: Bundle?) {
            Log.d("truthisvisible", truthisvisible) // prints "string"
            if (savedInstanceState != null){
                Log.d("LifecycleChange", "onActivityCreated savedInstanceState") // savedInstanceState is always null
            }
            super.onActivityCreated(savedInstanceState)
            Log.d("truthisvisible", truthisvisible) // prints "string"
            val print = arguments?.getString("success", "failure")
            Log.d("bool", "..." + print) // prints "...null"
    

我还尝试过在truthisvisible中更改变量onPause(),并尝试在onCreateView()中接收变量,但是变量从未更改为stringaftergetArguments()同样适用-参数不变。

此外,所有这些方法中的savedInstanceStatenull。尽管我希望这样做,因为onSaveInstanceState()在替换片段时不会触发。

我在这里完全死胡同。调用replace()时如何在片段中更改或保存变量?如果您好奇的话,这是我的父母活动:

var initialFragmentLoad = false

class TruthOrDare : FragmentActivity(), BottomNavigationView.OnNavigationItemSelectedListener {

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        if (!initialFragmentLoad){
            return true
        }
        val selectedFragment = when (item.itemId){
            R.id.action_leaderboards -> LeaderboardsFragment()
            R.id.action_options -> OptionsFragment()
            else -> GameFragment()
        }
        Log.d("ChosenFragment", selectedFragment.toString())
        val transaction = supportFragmentManager.beginTransaction().replace(R.id.fragment_layout, selectedFragment)
        transaction.addToBackStack(null)
        transaction.commit()
        return true
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_truth_or_dare)
        bottomNav_truthordare.setOnNavigationItemSelectedListener(this)
        bottomNav_truthordare.selectedItemId = R.id.action_game
        initialFragmentLoad = true
        if (savedInstanceState != null) {
            return
        }
        val firstFragment = GameFragment()
        firstFragment.arguments = intent.extras
        supportFragmentManager.beginTransaction().replace(R.id.fragment_layout, firstFragment).commit();
    }

}

我也想知道为什么为什么无法使用上述方法更改变量。

2 个答案:

答案 0 :(得分:0)

您可以使用处理程序类

public static class GameHandler {
  public static string truthisvisible;
}

然后打电话给

Gamehandler.truthisvisible = "stringafter";
val previousValue = Gamehandler.truthisvisible;

答案 1 :(得分:0)

您可以尝试像这样在onCreateView()中阻止片段重新放大它的视图

 if (view != null) {
    ViewGroup parent = (ViewGroup) view.getParent();
    parent.removeView(view);
 } else {
    //here you put your current code from `onCreateView()`
 }