DataBinding使用笔记一

时间:2021-02-09 16:20:36

好久没写博客了,不过自己笔记本会记录下一些日常笔记,时不时把它发表出来,聊以慰藉!


DataBinding使用笔记一



如何在使用安卓数据绑定(Data Binding)的时候使用动画

英文原文:Animating Android Binding Transitions 

安卓上新的binding framework可以轻松实现视图根据model的改变而改变。你只需要让model能被观测,然后framework会做好其余的事情。比如,你可以通过下面的代码来实现一个加载提示的显示和隐藏:

1

2

3

4

5

<ProgressBar

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_gravity="center"

    android:visibility="@{model.loading ? View.VISIBLE : View.GONE}"/>

容易被忽略的是如何让这种改变具有动画效果,比如,要是我们想让progress淡入淡出该咋办?

一种解决办法是使用自定义的@BindingAdapter来应用这种动画。- 参见官方文档对自定义绑定行为的解释。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@BindingAdapter("fadeVisible")

public static void setFadeVisible(final View view, boolean visible) {

    view.animate().cancel();

  

    if (visible) {

        view.setVisibility(View.VISIBLE);

        view.setAlpha(0);

        view.animate().alpha(1).setListener(new AnimatorListenerAdapter() {

            @Override

            public void onAnimationEnd(Animator animation) {

                view.setAlpha(1);

            }

        });

    } else {

        view.animate().alpha(0).setListener(new AnimatorListenerAdapter() {

            @Override

            public void onAnimationEnd(Animator animation) {

                view.setAlpha(1);

                view.setVisibility(View.GONE);

            }

        });

    }

}

1

2

3

4

5

<ProgressBar

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_gravity="center"

    app:fadeVisible="@{model.loading}"/>


但是,这种方式有个问题,每次值发生改变的时候都会产生动画效果,即使是在第一次绑定的时候。比如,你会在旋转屏幕的时候也看到淡入淡出。我们需要一种能判断是否是第一次绑定的办法。

可以利用viewtag不被保持的特点,如果没有tag,则这是第一次绑定,我们设置tag而不运行动画:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@BindingAdapter("fadeVisible")

public static void setFadeVisible(final View view, boolean visible) {

    if (view.getTag() == null) {

        view.setTag(true);

        view.setVisibility(visible ? View.VISIBLE : View.GONE);

    } else {

        view.animate().cancel();

  

        if (visible) {

            view.setVisibility(View.VISIBLE);

            view.setAlpha(0);

            view.animate().alpha(1).setListener(new AnimatorListenerAdapter() {

                @Override

                public void onAnimationEnd(Animator animation) {

                    view.setAlpha(1);

                }

            });

        } else {

            view.animate().alpha(0).setListener(new AnimatorListenerAdapter() {

                @Override

                public void onAnimationEnd(Animator animation) {

                    view.setAlpha(1);

                    view.setVisibility(View.GONE);

                }

            });

        }

    }

}

嗯,就是这样,加载提示便会很好的根据model的变化正确的显示淡入淡出了。

关于DataBinding替换新旧属性的使用

文/射覆(简书作者)

原文链接:http://www.jianshu.com/p/2047db8df2c7

著作权归作者所有,转载请联系作者获得授权,并标注简书作者


Binding适配器方法可能从handlers中获取旧的属性值. 同时获取新旧属性值的方法应该把旧的属性值作为参数放在前边,紧跟着是新的属性值:

@BindingAdapter("android:paddingLeft")

public static void setPaddingLeft(View view, int oldPadding, int newPadding) {

   if (oldPadding != newPadding) {

       view.setPadding(newPadding,

                       view.getPaddingTop(),

                       view.getPaddingRight(),

                       view.getPaddingBottom());

   }

}

事件处理器可仅在接口或者抽象类中使用,如:

@BindingAdapter("android:onLayoutChange")

public static void setOnLayoutChangeListener(View view, View.OnLayoutChangeListener oldValue,

       View.OnLayoutChangeListener newValue) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {

        if (oldValue != null) {

            view.removeOnLayoutChangeListener(oldValue);

        }

        if (newValue != null) {

            view.addOnLayoutChangeListener(newValue);

        }

    }

}


笔记:

学会使用@BindingAdapter,在adapters-1.0.jar包里面android.databinding.adapters

下已经实现了很多ViewBindingAdapter了,可以参照它们的用法。

理解Observable模式,DataBinding就是使用的观察者模式将view和model有序的结合。跟踪代码发现android.databinding.CallbackRegistry

是这个类更新了model绑定的view的。这个类可以做到在notify的时候remove掉callback不让removed callback再去notify的功能。是个很不错的实现方式,可以借鉴。

所有的LayoutBinding都继承自ViewDataBinding

这个类,这个类里面有用UIThreadHandlerChoreographer两种机制更新视图。

分别对应16版本以前和以后的。

所以可以肯定更新model最后导致view的更新就是在这个类里面完成的。但是发现代码跟踪到executeBindings()就跟踪不下去了,这个方法是个抽象类。

必须由子类具体实现,好吧,子类无法跟踪,,,,

mMainBinding.setData(mLoginModel)这个方法,就对应

<data>
    <
variable
       
name="data"
       
type="com.xiao.dong.myapplication.LoginModel"/>
</
data>

这个布局里的name=“data”参数

如果把这个改成name=“param”,编译器马上报错,说明这个setDataname=“data”对应的。

最后发现mvvm模式真的很方便,不过要习惯这种模式开发还需要一段时间的使用。