【问题标题】:change layout width with animation in android在android中用动画改变布局宽度
【发布时间】:2019-02-05 07:56:07
【问题描述】:

我尝试使用动画更改我的 relativeLayout 宽度。我的目标是使用动画将 WRAP_CONTENT 宽度更改为 MATCH_PARENT。这是我的源代码

private void setWidthAnimation(View view, int currentHeight, int newHeight) {
    ValueAnimator slideAnimator = ValueAnimator
            .ofInt(currentHeight, newHeight)
            .setDuration(1000);
    slideAnimator.addUpdateListener(animation -> {
        Integer value = (Integer) animation.getAnimatedValue();
        view.getLayoutParams().width = value.intValue();

        view.requestLayout();
    });
    AnimatorSet set = new AnimatorSet();

    set.play(slideAnimator);
    set.setInterpolator(new BounceInterpolator());
    set.start();
    view.setBackgroundColor(Color.RED);
}

我是这样调用这个方法的

  if (isKeyBoardOpen)
            setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
        else
            setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

但是当我运行我的应用程序时,视图的宽度发生了变化,但没有动画。谁能解释我做错了什么? 谢谢

【问题讨论】:

    标签: android android-layout android-animation


    【解决方案1】:

    您的代码的主要问题是您实际上没有真正的宽度值。

    如果您查看您的 setWidthAnimation() 方法,请查看它的位置:

    ValueAnimator slideAnimator = ValueAnimator
            .ofInt(currentHeight, newHeight)
            .setDuration(1000);
    

    特别是查看 currentHeightnewHeight。你知道这两个 int 变量的值是多少吗?

    setWidthAnimation(gifEditableLayout, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT);
    

    您使用ViewGroup.LayoutParams.WRAP_CONTENTViewGroup.LayoutParams.MATCH_PARENT 作为宽度值。但是,这些都不是您的视图的实际宽度。

    相反,它们只是LayoutParams 的静态常量:

    • MATCH_PARENT 是静态 int 常量,值为 -1

    • WRAP_CONTENT 是静态 int 常量,值为 -2

    因此,您实际上是在告诉 ValueAnimator 在 1 秒的持续时间内从 -1 到 -2 或 -2 到 -1 的值进行动画处理。

    此外,您只需将 -1 或 -2 设置为 LayoutParam 的宽度。幸运的是,这确实实现了 View 的完成外观,因为 View 的宽度可以有 3 种可能性:

    • layoutParams.width = -1; 这与调用FILL_PARENTMATCH_PARENT 相同

    • layoutParams.width = -2;这与调用WRAP_CONTENT

    • 相同
    • layoutParams.width = ANY_OTHER_INT; 这与直接将宽度设置为此值相同。

    但是,不会发生动画。

    原因很简单,因为 ValueAnimator 实际上不做任何动画。您可以将其更多地视为数字计数器。您已将其编码为在 1 秒的时间跨度内计算从 -1 到 -2 的 int 值。所以当它开始时,它位于WRAP_CONTENT。下一个可能的 int 值是 -2,这是最终值,因此它将在 1 秒后准确更新。一秒钟后,它会更新并运行将视图宽度设置为 -2 的代码。这会立即强制视图为MATCH_PARENT

    因此,要解决此问题,您需要将实整数值传递给您的 setWidthAnimation() 方法。

    【讨论】:

    • 感谢您的回复。很有帮助
    【解决方案2】:

    我真的不知道你的代码是什么,但我可以向你建议我的选择:将你的亲戚放在约束中并使用约束集动画。 启动xml

    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/rootContainer"
        tools:context=".MainActivity">
    
        <RelativeLayout
            android:id="@+id/rLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
        </RelativeLayout>
    

    和代码:

    RelativeLayout layout;
    ConstraintLayout root;
    
    ... 
    
    layout = findViewById(R.id.rLayout);
    root = findViewById(R.id.rootContainer);
    
    public void animate() {
        ConstraintLayout.LayoutParams params = new ConstraintLayout.LayoutParams(0, 0);
        layout.setLayoutParams(params);
        ConstraintSet set = new ConstraintSet();
        set.clone(root);
        set.connect(layout.getId(), ConstraintSet.BOTTOM, root.getId(), ConstraintSet.BOTTOM);
        set.connect(layout.getId(), ConstraintSet.TOP, root.getId(), ConstraintSet.TOP);
        set.connect(layout.getId(), ConstraintSet.LEFT, root.getId(), ConstraintSet.LEFT);
        set.connect(layout.getId(), ConstraintSet.RIGHT, root.getId(), ConstraintSet.RIGHT);
        AutoTransition transition = new AutoTransition();
        transition.setDuration(1000);
        TransitionManager.beginDelayedTransition(root, transition);
        set.applyTo(root);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-18
      • 2014-02-28
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 2022-08-14
      • 1970-01-01
      相关资源
      最近更新 更多