首页 > 解决方案 > 片段过渡导致崩溃

问题描述

我通过向右或向左滑动屏幕来更改带有动画的片段。这是父片段:

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()
        }
        childFragmentManager.beginTransaction()
        .replace(R.id.stats_container, fragmentStatsCat)
        .commit()

        view.setOnTouchListener {_, event ->

            when(event.action) {
                MotionEvent.ACTION_DOWN -> {
                    x = event.x
                }
                MotionEvent.ACTION_MOVE -> {
                    if(x != null) {
                        val dx = event.x - x!!
                        if(dx > 200f) {
                            inflateCategory()
                            x = event.x
                        }
                        if (dx < -200f) {
                            inflateMonth()
                            x = event.x
                        }
                    }
                }
            }

            true
        }

        return view
    }

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

        childFragmentManager.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

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

这工作正常,但有一个例外。当我执行 fragmentTransaction 时,虽然旧的 fragmentTransaction 尚未完成,但它会因“java.lang.IllegalStateException”而崩溃:“必须仅在所有者的初始化阶段创建重新启动器”

有没有办法在执行新交易之前检查旧交易是否已完成?

编辑:进一步解释我到底想要做什么:

子片段 1

子片段 2

我想通过在屏幕上滑动到另一个片段或触摸“按类别/月份排序”来在这两个子片段之间进行更改。

标签: androidfragment

解决方案


当另一个仍在进行时,您无法运行片段事务。根据您的代码在做什么,当用户在您的视图上滑动时,将会有多个触发器。这将快速连续触发多个片段事务,这就是导致您崩溃的原因。

在您的用例中,您只是想通过滑动在两个片段之间进行切换。实际上有一个小部件。

它被称为ViewPager

请参阅此处的官方 android 文档站点上的一些指南。

您还可以使用TabLayoutViewPager来制作上面的屏幕截图。


推荐阅读