在活动之间导航时重置运动布局

时间:2019-01-02 06:46:11

标签: android-motionlayout

我在mainactivity中使用动作布局。它工作正常。但是,当我移到其他活动并导航回我的mainactivity时,有时会重置该活动并且布局处于开始状态。如何防止这种情况发生?除此之外  我还问过here

有关运动布局的另一个问题

5 个答案:

答案 0 :(得分:6)

我要做的是添加一个字段,一个布尔型字段,并使用生命周期来处理它。

    private var hasMotionScrolled = false

    override fun onResume() {
        super.onResume()
        if (hasMotionScrolled) motionLayout.progress = MOTION_TRANSITION_COMPLETED
    }

    override fun onPause() {
        super.onPause()
        hasMotionScrolled = motionLayout.progress > MOTION_TRANSITION_INITIAL
    }


    companion object {
        private const val MOTION_TRANSITION_COMPLETED = 1F
        private const val MOTION_TRANSITION_INITIAL = 0F
    }

因此,在我的情况下,动作布局正在制作与滚动相关的动画。如果不是您的情况,也许您可​​以直接使用motionLayout.progress。我直接使用progress的问题是,中间状态会使向后导航时其他元素不可见,这就是为什么要实现一个全或全布尔标志。

我不认为这是一个干净的解决方案,标志始终是意味着其他事情可能会更好的东西,如果您可以找到官方的东西,请在评论中让我知道。

答案 1 :(得分:1)

class ExtMotionLayout : MotionLayout {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onSaveInstanceState(): Parcelable? {
        return SavedState(progress, super.onSaveInstanceState())
    }

    override fun onRestoreInstanceState(state: Parcelable?) {
        if (state is SavedState) {
            progress = state.progress
            super.onRestoreInstanceState(state.superState)
        } else super.onRestoreInstanceState(state)
    }

    class SavedState : BaseSavedState {
        val progress: Float

        constructor(progress: Float, source: Parcelable?) : super(source) {
            this.progress = progress
        }

        constructor(superState: Parcel) : super(superState) {
            progress = superState.readFloat()
        }

        override fun writeToParcel(out: Parcel, flags: Int) {
            super.writeToParcel(out, flags)
            out.writeFloat(progress)
        }
    }
}

答案 2 :(得分:1)

这就是我使用 Fragment

的方式

在您的 Fragment 类上创建一个实例变量:

var motionProgress = 0f // 0f being initial state

在您的 onViewCreated 函数上,为布局提供当前值:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.motionLayout.progress = motionProgress
}

最后,当导航离开 Fragment 时,更新函数 motionProgressonPause 的值:

override fun onPause() {
    super.onPause()

    motionProgress = binding.motionLayout.progress
}

答案 3 :(得分:0)

您可以将过渡侦听器添加到运动布局,并在过渡完成后保存标志。然后,当重新创建活动时,您可以读取该标志并使用类似以下的方式:motionLayout.setState(R.id.end,ConstraintSet.WRAP_CONTENT,ConstraintSet.WRAP_CONTENT)-其中R.id.end是来自ConstrainSetEnd属性的ID。

答案 4 :(得分:-1)

您必须保存/恢复MotionLayout的进度:

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putFloat("progress", motionLayout.progress)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        if (savedInstanceState != null)
            motionLayout.progress = savedInstanceState.getFloat("progress", 0f)
        ...
    }