Android中使用DataBinding时动画视图

时间:2016-11-21 12:16:16

标签: android animation data-binding

我已经开始在我的一个项目中使用DataBinding,并且在管理视图和动画时遇到了问题。我在我的应用程序中使用DataBinding,并在设置某个布尔值时使用BindingAdapters为视图设置动画。我使用了this post中描述的类似方法。

在我试图使用DataBinding实现的动画中,我在屏幕中间有一个搜索栏,下面有一个列表。当用户点击searchBar时,它会动画显示在屏幕顶部,列表会滚动到屏幕底部。 (拆分中心型动画)

我的模型中有一定的布尔值,当单击searchButton时设置为true,并且BoleanAdapter在布尔值中监听该更改,为视图设置动画。我可以获得需要设置动画的视图,但视图动画的数量取决于另一个视图的大小,而该视图未在BindingAdapter中传递。有没有办法在BindingAdapter中传入多个视图?我的第二个问题是,由于搜索栏和列表都会对相同值的更改进行动画处理,但我如何确保它们同时进行动画处理。如果我使用2个objectAnimators,我可以使用AnimatorSet并确保同步,但是如何使用DataBinding执行此操作?

public class AnimHelper {

@BindingAdapter({"animatev1", "app:model"})
public static void Animate1(View view, boolean b, final Model model) {
    if (b) {
        ObjectAnimator a = ObjectAnimator
                .ofFloat(view, View.TRANSLATION_Y, -view.getHeight())
                .setDuration(2000);
        a.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                model.setAnim2(true);
            }
        });

        a.start();
    }
}

@BindingAdapter({"animatev2", "app:model"})
public static void Animate2(View view, boolean anim, final Model model) {
    if (anim) {
        ObjectAnimator a = ObjectAnimator
                .ofFloat(view, View.TRANSLATION_Y, view.getHeight())
                .setDuration(2000);
        a.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
            }
        });

        a.start();
    }
}
}

xml文件如下:

<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">

<data>

    <variable
        name="searchviewmodel"
        type="com.example.mvvmvariableupdatinginanimend.ViewModel" />
</data>

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:animatev1="@{searchviewmodel.model.anim1}"
        android:background="@android:color/transparent" >

        <android.support.design.widget.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:titleEnabled="false">

            <TextView
                android:id="@+id/search_button"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_marginBottom="4dp"
                android:layout_marginLeft="8dp"
                android:layout_marginRight="8dp"
                android:layout_marginTop="202dp"
                android:background="#fff"
                android:drawableLeft="@android:drawable/ic_menu_search"
                android:drawablePadding="12dp"
                android:gravity="center_vertical"
                android:hint="Search Button1..."
               android:onClick="@{searchviewmodel.playSearchAnimation}"
                android:textSize="16sp" />
        </android.support.design.widget.CollapsingToolbarLayout>
    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/scrl_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="visible"
        app:animatev1="@{searchviewmodel.model.anim1}"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" >
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/lorem_ipsum"/>
    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

在上面的SearchBar点击代码中,我将anim1设置为true,之前编写的BindingAdapter在侦听anim1中的更改​​时执行AppbarLayout和NestedScrollView的动画。这似乎按预期工作,但我想在我的动画中考虑状态栏和searchButton的高度,这当前没有发生,因为我没有在AnimHelper的Animate1函数中获取这些视图。

1 个答案:

答案 0 :(得分:1)

您应该能够将其他视图作为值传递给绑定表达式。

<TextView ...
    app:animatev1="@{...}"
    app:otherView="@{myOtherView}"/>
<TextView android:id="@+id/myOtherView" .../>

然后,您的绑定适配器可以同时使用这两个参数:

@BindingAdapter({"animatev1", "otherView"})
public static void animateV1(View view, boolean b, View otherView) {
    //...
}

至于你的第二个问题,我认为你不应该担心同步问题。他们应该同时开始制作动画。

使用数据绑定在两个不同的视图上使用AnimatorSet没有好办法。您可以通过将一个View传递给另一个绑定适配器并在同一个绑定适配器中为它们设置动画来实现。但那不是一个好选择。最好只在不同的绑定适配器中单独为它们设置动画,并依靠框架来做正确的事情。