【问题标题】:Animate LayoutParams changes in ConstraintLayout对 ConstraintLayout 中的 LayoutParams 更改进行动画处理
【发布时间】:2017-10-06 15:45:12
【问题描述】:

我正在创建应用程序,其中有带有搜索栏by this lib 的屏幕。 我的活动布局如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<android.support.constraint.ConstraintLayout
        android:id="@+id/wrapper"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true">

    <TextView
            android:id="@+id/title"
            android:textColor="@color/colorPrimary"
            android:text="@string/mainScreenTitle"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textAlignment="center"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:paddingTop="100dp"/>

    <com.arlib.floatingsearchview.FloatingSearchView
            android:id="@+id/searchView"
            android:layout_width="0dp"
            android:layout_height="50dp"
            android:layout_marginTop="100dp"
            android:animateLayoutChanges="true"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/title"/>

</android.support.constraint.ConstraintLayout>

</RelativeLayout>

我必须将 FloatingSearchingView 移动到屏幕顶部并将高度更改为例如 500dp - 像这样:

app:layout_constraintTop_toTopOf="parent"
android:layout_height="500dp"

稍后我将不得不将其移回并再次将高度更改为默认值

app:layout_constraintTop_toBottomOf="@+id/title"
android:layout_height="50dp"

问题是,我必须为它制作动画。我花了很多时间寻找解决方案,但不幸的是我没有找到任何东西。

【问题讨论】:

    标签: android animation layoutparams android-constraintlayout


    【解决方案1】:

    我必须在 ConstraintLayout 中设置 TextView 高度的动画。

     <androidx.constraintlayout.widget.ConstraintLayout
                    ...
                    android:animateLayoutChanges="true"
                    >
    
                    <TextView
                     ...
    

    我首先通知了 ConstraintLayout 布局即将改变:

    constraintlayout.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
    

    然后更新 textView 高度(或其他任何参数)

    textView.getLayoutParams().height = 200;
    textView.requestLayout();
    

    对于这么简单的事情,不需要设置动画师或涉及其他库。

    【讨论】:

    • 这完美!还不知道这个。我理解 requestLayout() 的必要性,但不知何故,没有它它也可以工作。可能只适用于较新的 SDK 版本。编辑:“这从 API 11 又名 Honeycomb 就已经存在了”天哪! proandroiddev.com/…
    【解决方案2】:

    不幸的是,@beeb 的版本对我也不起作用。虽然问题很老,但这是一个对我有用的解决方案,使用 TransitionManager。这有点“冗余”,因为您必须复制一些代码,但因此非常简单,只包括两个基本步骤:

    1. 创建两个 layout.xml 文件。每个状态一个(动画之前/之后)。 如果您的约束布局是父布局的多个子布局之一,您可以创建两个仅包含此约束布局的文件,并通过 &lt;include @layout=""/&gt; 在应用启动时包含您不想要的版本,之前你的约束布局已经。这样,您不必复制整个布局文件。然而,当我的包含元素有一个 id 时,这会导致 findViewById() 方法返回 null。所以要小心这个。

    在您的情况下,例如:floating_searching_view_at_bottom.xml

    <com.arlib.floatingsearchview.FloatingSearchView
        android:id="@+id/searchView"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginTop="100dp"
        android:animateLayoutChanges="true"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title"
        android:layout_height="50dp" />
    

    floating_searching_view_at_top.xml:

    <com.arlib.floatingsearchview.FloatingSearchView
        android:id="@+id/searchView"
        android:layout_width="0dp"
        android:layout_height="50dp"
        android:layout_marginTop="100dp"
        android:animateLayoutChanges="true"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/title"
        android:layout_height="50dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_height="500dp" />
    
    1. 使用 TransitionManager 为这些布局文件之间的过渡设置动画:
    boolean toggle = false // you should give this guy a more descriptive name!
    Context context = this; // in scope of the activity.
    
    public void animateTransition() {
        // Load ConstraintSets from the two layouts
        ConstraintSet atBottom = new ConstraintSet();
        ConstraintSet atTop    = new ConstraintSet();
        atBottom.clone(context, R.layout.floating_searching_view_at_bottom);
        atTop.clone(context, R.layout.floating_searching_view_at_top);
    
        // apply ConstraintSet depending on "toggle"
        ConstraintSet newLayout = (toggle) ? expanded : collapsed;
        TransitionManager.beginDelayedTransition(constraintLayout); 
        newLayout.applyTo(constraintLayout);
    
        // invert the toggle
        toggle = !toggle;
    }
    

    注意: 1. 确保 context 是 Activity 类型,并且您使用的是 AppCompat 主题。不小心用了getApplicationContext(),什么 显然导致了崩溃。 2. 如果你收到 NPE 的约束k

    【讨论】:

      【解决方案3】:

      尝试为此使用Animation 类:

      Animation animation = new Animation() {
      
          @Override
          protected void applyTransformation(float interpolatedTime, Transformation t) {
              LayoutParams params = yourView.getLayoutParams();
      
              // modify your layout params here
      
              yourView.setLayoutParams(params);
          }
      };
      animation.setDuration(500); // in ms
      yourView.startAnimation(animation);
      

      【讨论】:

      • 我在 applyTransformation 方法中做了 params.topToBottom = -1 和 params.topToTop = R.id.wrapper 但它仍然没有动画:c
      • 仍然没有动画
      猜你喜欢
      • 1970-01-01
      • 2012-03-30
      • 2016-01-21
      • 2017-01-14
      • 2019-09-10
      • 2013-08-19
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      相关资源
      最近更新 更多