Fragment onCreate(), onCreateView() & onActivityCreated() all called twice when parent Activity is created

时间:2019-04-08 12:55:38

标签: android xml android-fragments kotlin

I have an Activity with 3 child fragments - with only 1 showing at a time. I'm using a BottomNavigationView to switch between child fragments. The initial child fragment shown, GameFragment(), is inflated when the activity is created via supportFragmentManager.beginTransaction().add() which is added to my container fragment_layout in my xml FrameLayout.

This should be the only time the Fragment is created. However, my Log statements show:

D/LifecycleChange: Activity Created
D/LifecycleChange: onCreate GameFragment
D/LifecycleChange: onCreateView GameFragment
D/LifecycleChange: onActivityCreated
D/LifecycleChange: onCreate GameFragment
D/LifecycleChange: onCreateView GameFragment
D/LifecycleChange: onActivityCreated

that my fragment's onCreate(), onCreateView() & onActivityCreated() are called twice when the activity starts.

Main activity:

class TruthOrDare : FragmentActivity(), BottomNavigationView.OnNavigationItemSelectedListener {
    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        val selectedFragment = when (item.itemId){
            R.id.action_leaderboards -> LeaderboardsFragment()
            R.id.action_options -> OptionsFragment()
            else -> GameFragment()
        }
        val transaction = supportFragmentManager.beginTransaction()
        transaction.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)
        Log.d("LifecycleChange", "Activity Created")
        bottomNav_truthordare.setOnNavigationItemSelectedListener(this)
        bottomNav_truthordare.selectedItemId = R.id.action_game

        if (savedInstanceState != null) {
            Log.d("LifecycleChange", "Activity onSaveInstanceState is not null")
            return
        }
        val firstFragment = GameFragment()
        firstFragment.arguments = intent.extras
        supportFragmentManager.beginTransaction().add(R.id.fragment_layout, firstFragment).commit();
    }

Fragment

class GameFragment : Fragment(), View.OnClickListener {

    override fun onSaveInstanceState(outState: Bundle) {
        Log.d("LifecycleChange", "onSaveInstanceState GameFragment")
        super.onSaveInstanceState(outState)
        var truthdareisvisible = true
        if (truth.visibility != View.VISIBLE){
            truthdareisvisible = false
        }
        outState.putBoolean("truthdareisvisibile", truthdareisvisible)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        if (savedInstanceState != null){
            Log.d("LifecycleChange", "onActivityCreated savedInstanceState is not null")
            val truthdareisvisible = savedInstanceState.getBoolean("truthdareisvisibile")
            if (truthdareisvisible) truth.visibility == View.VISIBLE
        }
        Log.d("LifecycleChange", "onActivityCreated")
        super.onActivityCreated(savedInstanceState)
        val bundle = this.arguments
        if (bundle != null){
            playersinfo = bundle.getParcelable("playersinfo")
            players = playersinfo.players
            tempPlayers = ArrayList(players)
            numberOfPlayers = players.size
            _chosenPlayer = tempPlayers[Random.nextInt(numberOfPlayers)]
            chosenPlayer.text = _chosenPlayer.name
            truth.setOnClickListener(this)
            dare.setOnClickListener(this)
            complete.setOnClickListener(this)
            forfeit.setOnClickListener(this)
            fadeIn(chosenPlayer, 3000)
            writeText(chosenPlayer, "...", 200)
            Handler().postDelayed({showViews(listOf(truth, or, dare), 2000)}, 2000)
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        if (savedInstanceState != null) {
            Log.d("LifecycleChange", "onCreate GameFragment is not null")
            return
        }
        Log.d("LifecycleChange", "onCreate GameFragment")
        super.onCreate(savedInstanceState)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        Log.d("LifecycleChange", "onCreateView GameFragment")
        return inflater.inflate(R.layout.fragment_game, container, false)
    }

fragment_game.xml

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar_truthordare"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="@color/colorPrimaryDark"
    android:elevation="4dp"
    android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
    app:layout_constraintTop_toTopOf="parent"
    app:popupTheme="@color/colorPrimaryDark"
    app:title="Level 1" />

<FrameLayout
    android:id="@+id/fragment_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/bottomNav_truthordare" android:layout_below="@id/toolbar_truthordare">
</FrameLayout>

<android.support.design.widget.BottomNavigationView
    android:id="@+id/bottomNav_truthordare"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorPrimaryDark"
    app:itemIconTint="@color/bottom_nav_items"
    app:itemTextColor="@color/bottom_nav_items"
    android:layout_alignParentBottom="true"
    app:menu="@menu/menu" />

Any idea why this is?

PS: I can successfully switch between fragments, however onSaveInstanceState() is never called (e.g. in my GameFragment() above). onSaveInstanceState() in my fragment is only called when I leave the activity and come back (without making a fragment transaction in that time). Not sure if this is related in any way to the root problem.

0 个答案:

没有答案