我在mainactivity中使用动作布局。它工作正常。但是,当我移到其他活动并导航回我的mainactivity时,有时会重置该活动并且布局处于开始状态。如何防止这种情况发生?除此之外 我还问过here
有关运动布局的另一个问题答案 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
时,更新函数 motionProgress
上 onPause
的值:
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)
...
}