我有一个自定义选项卡视图,它派生了LinearLayout
一个 xml 布局。llIndicator
在它里面我有一个视图translationX
(
val offset = llIndicator.width * activeTabIndex
llIndicator.animate().translationX(offset.toFloat())
一切正常,唯一的问题是当我试图在活动被销毁并重新创建后恢复视图的状态时。大多数属性甚至不需要保存,因为片段中的设置代码被再次调用,但我想保存选定的选项卡并恢复 translationX 属性并在没有动画的情况下恢复它。
但我似乎找不到正确的解决方案。我将选定的选项卡保存到一个包中,成功恢复它,计算正确的位置,但是当我设置translationX
属性时,它什么也没做......
如果我在方法中执行它不起作用,onRestoreInstanceState()
因为它发生在布局之前,所以我尝试在方法中设置一个变量并在isInstanceBeingRestored
方法true
中onRestoreInstanceState()
设置,但没有成功。translationX
onLayout()
所以我也尝试OnGlobalLayoutListner()
通过将以下代码放在init{ }
视图中来使用。
viewTreeObserver.addOnGlobalLayoutListener(object: ViewTreeObserver.OnGlobalLayoutListener{
override fun onGlobalLayout() {
viewTreeObserver.removeOnGlobalLayoutListener(this)
// Restore view if needed
if(isInstanceBeingRestored){
llIndicator.translationX = offset
}
}
})
它仍然什么都不做......offset
计算正确,我使用检查过Log.d()
,并且用任何数字替换它都没有效果。
所以我尝试使用 post() 方法,如下:
llIndicator.post({
llIndicator.translationX = offset
})
我尝试将它放在onLayout()
方法中(当然isInstanceBeingRestored
首先检查变量),但也OnGlobalLayoutListener()
没有效果。
但有趣的是,如果我使用具有足够大延迟的 postDelayed(),它就可以工作。
llIndicator.postDelayed({
llIndicator.translationX = offset
}, 1500)
但显然,这个解决方案不能保留,我只是试了一下......所以我很困惑......这听起来很容易解决,但经过数小时的谷歌搜索和尝试不同的代码,摸不着头脑,我仍然无法解决不了。肯定不会这么难吧?
我究竟做错了什么?谁能指出我正确的方向?
非常感谢您的帮助。
编辑:
我发现了一些有趣的东西......如果我使用marginStart
而不是translationX
如下来设置它的工作位置。那会是什么原因呢?我不明白...
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
if(isInstanceBeingRestored){
val p = llIndicator.layoutParams as MarginLayoutParams
p.marginStart = offset.toInt()
llIndicator.layoutParams = p
//llIndicator.translationX = offset
}
}
编辑 2:
只有marginStart
在活动被破坏之前边距开始为 0 时才有效...因此,如果我设置offset
为一个随机值,独立于其先前的位置,它会在正确的位置显示指示器,如果marginStart
之前为 0。 .. 否则指示条出现在屏幕左侧。现在我真的迷路了......我仔细检查了计算,但它们给出了正确的偏移量......
最良好的祝愿,阿戈斯顿