Загрузка фрагмента внутри фрагмента не работает должным образом - PullRequest
1 голос
/ 15 июня 2019

У меня есть действие, которое использует фрагменты для изменения экрана.Я загружаю эти фрагменты в FrameLayout.

Activity: (я удалил не важные части)

<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activities.HomeActivity"
android:fitsSystemWindows="true">

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/content_frame_2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.drawerlayout.widget.DrawerLayout>

Внутри content_frame я загружаю фрагменты, и это работает, находят,с одним исключением.В одном из этих фрагментов есть другой FrameLayout, в котором я выбираю два разных фрагмента.Когда я загружаю этот фрагмент, все работает нормально, и я могу переключаться между двумя фрагментами.Но когда я оставляю фрагмент и снова открываю его, фрагмент внутри фрагмента не загружается.Иногда это также приводит к сбою:

2019-06-15 12:28:54.378 20353-20353/com.financetracker.financetracker E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.financetracker.financetracker, PID: 20353
java.lang.IllegalStateException: Restarter must be created only during owner's initialization stage
    at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:59)
    at androidx.fragment.app.Fragment.performCreate(Fragment.java:2595)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:831)
    at androidx.fragment.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManagerImpl.java:1228)
    at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:1293)
    at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:439)
    at androidx.fragment.app.FragmentManagerImpl.executeOps(FragmentManagerImpl.java:2066)
    at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1856)
    at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1811)
    at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1717)
    at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
    at android.os.Handler.handleCallback(Handler.java:761)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:156)
    at android.app.ActivityThread.main(ActivityThread.java:6523)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:942)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:832)

Редактировать: Статистика фрагмента (загружается в content_frame:

class StatsFragment: Fragment() {
    private lateinit var tvSortCategories: TextView
    private lateinit var tvSortMonths: TextView
    private var x: Float? = null
    private val fragmentStatsCat = StatsCategoryFragment()
    private val fragmentStatsMon = StatsMonthFragment()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view: View = inflater.inflate(R.layout.fragment_stats, container, false)
        tvSortCategories = view.findViewById(R.id.tvStatsCategories)
        tvSortMonths = view.findViewById(R.id.tvStatsMonths)
        tvSortCategories.isSelected = true
        tvSortCategories.setOnClickListener {
            inflateCategory()
        }
        tvSortMonths.setOnClickListener {
            inflateMonth()
        }
    }

    private fun inflateCategory() {
        tvSortCategories.isSelected = true
        tvSortMonths.isSelected = false


fragmentManager!!.beginTransaction().setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right).replace(R.id.stats_container, fragmentStatsCat).commit()
        }

    private fun inflateMonth() {
        tvSortCategories.isSelected = false
        tvSortMonths.isSelected = true


fragmentManager!!.beginTransaction().setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left).replace(R.id.stats_container, fragmentStatsMon).commit()
        }
    }

Статистика фрагмента1 (загружается в FrameLayoutприведенный выше фрагмент)

class StatsMonthFragment: Fragment() {

private lateinit var btnPrevCat: ImageButton
private lateinit var btnNextCat: ImageButton
private lateinit var cbAllCats: CheckBox
private lateinit var categories: List<Category>
private var i: Int = 0

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_stats_months, container, false)

    btnNextCat = view.findViewById(R.id.btn_next_cat)
    btnPrevCat = view.findViewById(R.id.btn_prev_cat)
    cbAllCats = view.findViewById(R.id.cb_all_cats)
    categories = DatabaseInitializer.getInstance().getAllCategories(AppDatabase.getInstance(context).categoryDao())
    if(categories.isEmpty()) {
        cbAllCats.visibility = View.GONE
        btnPrevCat.visibility = View.GONE
        btnNextCat.visibility = View.GONE

        //In Statistik schreiben, dass nichts vorhanden ist
    } else {
        val initFragment = StatsSelectedFilterFragment()
        initFragment.setText(categories[i].cat_name)
        fragmentManager!!.beginTransaction().add(R.id.container_stats_categories, initFragment).commit()


        btnNextCat.setOnClickListener {
            increaseIndex()
            val fragment = StatsSelectedFilterFragment()
            fragment.setText(categories[i].cat_name)
            fragmentManager!!.beginTransaction()
                    .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
                    .replace(R.id.container_stats_categories, fragment)
                    .commit()
        }
        btnPrevCat.setOnClickListener {
            decreaseIndex()
            val fragment = StatsSelectedFilterFragment()
            fragment.setText(categories[i].cat_name)
            fragmentManager!!.beginTransaction()
                    .setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
                    .replace(R.id.container_stats_categories, fragment)
                    .commit()
        }

        cbAllCats.setOnCheckedChangeListener{_,checked->
            if(checked) {
                btnPrevCat.isClickable = false
                btnNextCat.isClickable = false
                btnNextCat.isEnabled = false
                btnPrevCat.isEnabled = false
                val fragment = StatsSelectedFilterFragment()
                fragment.setText(getString(R.string.all_categories))
                fragmentManager!!.beginTransaction()
                        .replace(R.id.container_stats_categories, fragment)
                        .commit()
            } else {
                btnPrevCat.isClickable = true
                btnNextCat.isClickable = true
                btnNextCat.isEnabled = true
                btnPrevCat.isEnabled = true
                val fragment = StatsSelectedFilterFragment()
                fragment.setText(categories[i].cat_name)
                fragmentManager!!.beginTransaction()
                        .replace(R.id.container_stats_categories, fragment)
                        .commit()
            }
        }
    }

    return view
}

private fun increaseIndex() {
    if(i == categories.size - 1) {
        i = 0
    } else {
        i++
    }
}

private fun decreaseIndex() {
    if(i == 0) {
        i = categories.size - 1
    } else {
        i--
    }
}

private fun createNewGraph() {

}
}

Frags Stats2 (также загружается в вышеуказанный фрагмент Stats)

class StatsCategoryFragment: Fragment() {

private lateinit var btnPrevYear: ImageButton
private lateinit var btnNextYear: ImageButton
private lateinit var btnPrevMonth: ImageButton
private lateinit var btnNextMonth: ImageButton
private lateinit var cbEntYear: CheckBox
private val cal = Calendar.getInstance()
private var curMonth: Int? = null
private var curYear: Int? = null

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view = inflater.inflate(R.layout.fragment_stats_categories, container, false)

    btnPrevYear = view.findViewById(R.id.btn_prev_year)
    btnNextYear = view.findViewById(R.id.btn_next_year)
    btnPrevMonth = view.findViewById(R.id.btn_prev_month)
    btnNextMonth = view.findViewById(R.id.btn_next_month)
    cbEntYear = view.findViewById(R.id.cb_entire_year)
    curYear = cal.get(Calendar.YEAR)
    curMonth = cal.get(Calendar.MONTH) + 1
    val monthFragment = StatsSelectedFilterFragment()
    monthFragment.setText(getMonthString(getMonthEnum(curMonth!!)!!))
    val yearFragment = StatsSelectedFilterFragment()
    yearFragment.setText(curYear!!.toString())
    fragmentManager!!.beginTransaction().add(R.id.container_stats_month, monthFragment).commit()
    fragmentManager!!.beginTransaction().add(R.id.container_stats_year, yearFragment).commit()

    btnPrevYear.setOnClickListener {
        decreaseYear()
        val fragment = StatsSelectedFilterFragment()
        fragment.setText(curYear.toString())
        fragmentManager!!.beginTransaction()
                .setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
                .replace(R.id.container_stats_year, fragment)
                .commit()
    }
    btnNextYear.setOnClickListener {
        increaseYear()
        val fragment = StatsSelectedFilterFragment()
        fragment.setText(curYear.toString())
        fragmentManager!!.beginTransaction()
                .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
                .replace(R.id.container_stats_year, fragment)
                .commit()
    }
    btnPrevMonth.setOnClickListener {
        val decYear = decreaseMonth()
        val fragment = StatsSelectedFilterFragment()
        fragment.setText(getMonthString(getMonthEnum(curMonth!!)!!))
        fragmentManager!!.beginTransaction()
                .setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
                .replace(R.id.container_stats_month, fragment)
                .commit()

        if(decYear) {
            val fragmentY = StatsSelectedFilterFragment()
            fragmentY.setText(curYear.toString())
            fragmentManager!!.beginTransaction()
                    .setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
                    .replace(R.id.container_stats_year, fragmentY)
                    .commit()
        }
    }
    btnNextMonth.setOnClickListener {
        val incYear = increaseMonth()
        val fragment = StatsSelectedFilterFragment()
        fragment.setText(getMonthString(getMonthEnum(curMonth!!)!!))
        fragmentManager!!.beginTransaction()
                .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
                .replace(R.id.container_stats_month, fragment)
                .commit()

        if(incYear) {
            val fragmentY = StatsSelectedFilterFragment()
            fragmentY.setText(curYear.toString())
            fragmentManager!!.beginTransaction()
                    .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
                    .replace(R.id.container_stats_year, fragmentY)
                    .commit()
        }
    }

    cbEntYear.setOnCheckedChangeListener {_, checked->
        if(checked) {
            btnPrevMonth.isClickable = false
            btnNextMonth.isClickable = false
            btnPrevMonth.isEnabled = false
            btnNextMonth.isEnabled = false
            val fragment = StatsSelectedFilterFragment()
            fragment.setText(getString(R.string.every_month))
            fragmentManager!!.beginTransaction().replace(R.id.container_stats_month, fragment).commit()
        } else {
            btnPrevMonth.isClickable = true
            btnNextMonth.isClickable = true
            btnPrevMonth.isEnabled = true
            btnNextMonth.isEnabled = true
            val fragment = StatsSelectedFilterFragment()
            fragment.setText(getMonthString(getMonthEnum(curMonth!!)!!))
            fragmentManager!!.beginTransaction()
                    .replace(R.id.container_stats_month, fragment)
                    .commit()
        }
    }

    return view
}

private enum class Month {
    JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
}

private fun getMonthEnum(month: Int): Month? {
    return when(month) {
        1 -> Month.JANUARY
        2 -> Month.FEBRUARY
        3 -> Month.MARCH
        4 -> Month.APRIL
        5 -> Month.MAY
        6 -> Month.JUNE
        7 -> Month.JULY
        8 -> Month.AUGUST
        9 -> Month.SEPTEMBER
        10 -> Month.OCTOBER
        11 -> Month.NOVEMBER
        12 -> Month.DECEMBER
        else -> null
    }
}

private fun getMonthString(month: Month): String {
    return when (month) {
        Month.JANUARY -> getString(R.string.january)
        Month.FEBRUARY -> getString(R.string.february)
        Month.MARCH -> getString(R.string.march)
        Month.APRIL -> getString(R.string.april)
        Month.MAY -> getString(R.string.may)
        Month.JUNE -> getString(R.string.june)
        Month.JULY -> getString(R.string.july)
        Month.AUGUST -> getString(R.string.august)
        Month.SEPTEMBER -> getString(R.string.september)
        Month.OCTOBER -> getString(R.string.october)
        Month.NOVEMBER -> getString(R.string.november)
        Month.DECEMBER -> getString(R.string.december)
    }
}

private fun increaseMonth(): Boolean {
    return if(curMonth == 12) {
        curMonth = 1
        increaseYear()
        true
    } else {
        curMonth = curMonth!! + 1
        false
    }
}

private fun decreaseMonth(): Boolean {
    return if(curMonth == 1) {
        curMonth = 12
        decreaseYear()
        true
    } else {
        curMonth = curMonth!! - 1
        false
    }
}

private fun increaseYear() {
    curYear = curYear!! + 1
}

private fun decreaseYear() {
    curYear = curYear!! - 1
}

private fun createNewGraph() {

}
}
...