如何通过WindowManager.UpdateViewLayout移动视图而不带任何动画?

5
当我执行以下操作时:
    LayoutParams lp = getLayoutParams(view);
    lp.x = absoluteX;
    lp.y = absoluteY;
    this.mWindowManager.updateViewLayout(view, lp);

我需要将一个视图从当前位置移动到新的绝对位置absoluteX/absoluteY,但不需要进行任何动画效果。如何实现呢?

我已经尝试设置lp.windowAnimations = 0,但是没有任何变化 :( 您有什么建议吗?

如果无法避免动画效果,是否有一种方法可以知道视图的实际位置?也许我可以让它不可见,直到真正的位置达到absoluteX/absoluteY。

注意:

查看Android源代码时,我在WindowManager.java文件中看到了以下条目:

     /**
     * Never animate position changes of the window.
     *
     * {@hide} */
    public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 0x00000040;

    /**
     * Control flags that are private to the platform.
     * @hide
     */
    public int privateFlags;

看起来这正是我需要的,但我不知道如何访问和设置这样的标志:( 有什么想法吗?


2
你可以尝试使用 removeView() 方法将视图移除,然后立即使用更新后的 LayoutParams 将其添加回去。 - Mike M.
Mike M,有效地执行RemoveView和AddView会删除动画,但这真的是最好的方法吗?我查看了Android源代码,发现布局参数具有PRIVATE_FLAG_NO_MOVE_ANIMATION和public int privateFlags;也许我应该尝试调整这个参数? - zeus
1
我们通过遵循这个答案解决了这个问题。使用反射来禁用私有标志动画。https://dev59.com/K3PYa4cB1Zd3GeqPi3EN#33171254 - Kevin Marlow
@MikeM。谢谢,那解决了我的问题! - Alexey Andronov
关于@Kevin Marlow提出的解决方案,即使禁用动画标志,仍然存在闪烁问题。 - Alexey Andronov
显示剩余2条评论
2个回答

1
尝试禁用布局动画:

try to disable the layout animation:

android:animateLayoutChanges="false"

此回复并未提供解决问题的答案。如果您有批评意见或需要向作者请求澄清,请在其帖子下方留言。- 【来自评论审核】 - Aditya Vyas-Lakhan
他正在询问如何在没有动画的情况下移动视图,据我所知,这个属性可以禁用由布局更改引起的动画。 - Metwalli
谢谢Jamal,但不幸的是它没有起作用:( 我尝试像这样设置它 <style name="AppTheme" parent="@android:style/Theme.Material.Light.NoActionBar"> <item name="android:animateLayoutChanges">false</item> </style> - zeus

1
val lp = WindowManager.LayoutParams(
    width, 
    height, 
    this.windowManagerType(),
    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
    or WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
    or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
    or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
    PixelFormat.TRANSPARENT
)

val className = "android.view.WindowManager\$LayoutParams"
try {
    val layoutParamsClass = Class.forName(className)
    val privateFlags = layoutParamsClass.getField("privateFlags")
    val noAnim = layoutParamsClass.getField("PRIVATE_FLAG_NO_MOVE_ANIMATION")

    var privateFlagsValue = privateFlags.getInt(lp)
    val noAnimFlag = noAnim.getInt(lp)
    privateFlagsValue = privateFlagsValue or noAnimFlag
    privateFlags.setInt(lp, privateFlagsValue)
} catch (e: Exception) {
    Log.e("EXCEPT", "EXCEPTION: ${e.localizedMessage}")
}

我一直为这个奇怪的动画问题苦恼,认为它是布局传递或我的动画逻辑的问题。绝对是一个很好的发现。 - Selali Adobor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接