Android进阶十九 Databinding使用总结

String组合

<string name="common_percent">%1$s%2$s</string>
 <data >
        <variable
            name="value"
            type="int"/>
</data>
android:text="@{@string/common_percent(Integer.toString(value),ConstantData.PERCENT_SYM)}"
public static final String PERCENT_SYM = "%";

对于非string类型,需要进行转换Integer.toString(value),如要用到“%“,直接放在strings.xml中会出错,这边在java里面定义:

public static final String PERCENT_SYM = "%";

View或layout背景设置

 <data >
     <variable
         name="id"
         type="int"/>
</data>
<RelativeLayout
                    android:id="@+id/id_group_one_bg"
                    android:layout_width="208px"
                    android:layout_height="340px"
                    android:layout_marginTop="5px"
                    app:backgroundResource = "@{id}">
</RelativeLayout>

对于ImageView,因为对应setter的参数不是一个int的id,所以不能用android:src="@{id}"或者android:background="@{id}",需要设置ImageView的src或者backround,可以使用app:backgroundResource,或者使用@BindingMethod或者@BindingAdapter

数组传递

        <variable
            name="strings"
            type="String[]"/>

        <variable
            name="ints"
            type="int[]"/>

ObservableField< ClassBean>中对象的更新

这时候如果ClassBean如果有正向绑定的参数,这样正向绑定不会成功,即改变ObservableField中对象的值(对象相应值有做正向绑定),但是View中的显示不改变,这时候加上notifyChange()或者:

     mClassBean.get().setText("xxx");
     mClassBean.notifyChange();

资源直接相加

android:marginLeft="@{@dimen/margin + @dimen/avatar_size}"
android:text="@{user.nickName + `(` + user.name + `)`}"

隐式更新

<CheckBox android:id=”@+id/seeAds“/>
<ImageView android:visibility=“@{seeAds.checked ?
  View.VISIBLE : View.GONE}”/>//checkbox改变时,ImageView随之改变

隐式更新只有少数属性支持,如果自定义属性要使用隐式更新,需要定义反向绑定(见Android进阶六:Databinding的双向绑定)
举个栗子:

 <com.test.view.ExLinearLayout
        android:layout_width="225px"
        android:layout_height="56px"
        android:id = "@+id/layoutMain"
        >
        <ImageView
            android:layout_width="32px"
            android:layout_height="32px"
            android:background="@drawable/ic_edit"
            android:pressed = "@{layoutMain.highlight?false:true}"
            />
    </com.test.view.ExLinearLayout>
@InverseBindingMethods(@InverseBindingMethod(type = ExLinearLayout.class,attribute = "highlight"))
public class ExLinearLayout extends LinearLayout {
    private boolean highlight;
    private static InverseBindingListener highlightInverseBindingListener;

    public ExLinearLayout(Context context) {
        super(context);
    }

    public ExLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ExLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public boolean isHighlight()
    {
        return (this.isPressed() || this.isSelected());
    }

    public void setHighlight(boolean highlight)
    {
        this.highlight = highlight;
    }

    @Override
    public void setPressed(boolean pressed) {
        super.setPressed(pressed);
        highlightInverseBindingListener.onChange();
    }

    @Override
    public void setSelected(boolean selected) {
        super.setSelected(selected);
        highlightInverseBindingListener.onChange();

    }

    @BindingAdapter("highlightAttrChanged")
    public static void setHighlightChangedListener(ExLinearLayout exLinearLayout,final InverseBindingListener bindingListener) {
        highlightInverseBindingListener = bindingListener;
    }
}

动态binding类

在不知道具体生成的binding类的时候(Recyclerview的多种ViewHolder)

public class BindingViewHolder<T extends ViewDataBinding> extends RecyclerView.ViewHolder {

    protected final T mBinding;

    public BindingViewHolder(T binding) {
        super(binding.getRoot());
        mBinding = binding;
    }

    public T getBinding() {
        return mBinding;
    }
}

// 通过上面的泛型获取相应的ViewDataBinding
public void onBindViewHolder(BindingHolder holder, int position) {
   final T item = mItems.get(position);
   holder.getBinding().setVariable(BR.item, item);
   holder.getBinding().executePendingBindings();
}

避免空指针

google的databinding类会自动为我们避免空指针

android:text="@{user.firstName}"//如果user为null,则user.firstName = null

给属性添加变化监听

1.当数据模型的某些属性值发生变化时,我们可能要做一些业务处理,那我们怎么才能捕捉到Model属性的变化呢?通过addOnPropertyChangedCallback可以捕捉到属性的改变。

binding.addOnPropertyChangedCallback(new Observable.OnPropertyChangedCallback() {
        @Override
        public void onPropertyChanged(Observable observable, int i) {
            if (i == BR.name) {

            }
        }
    });

2.绑定发生改变的时候,如果要动画可以使用addOnRebindCallback,这个方法是设置绑定周期的监听器的方法,也就是说在整个绑定周期中,OnRebindCallback中的方法会被调用。比如说onPreBind(ViewDataBinding binding)会在executeBindings()调用之前被调用。onCanceled(T binding) 会在绑定取消的时候调用。

binding.addOnRebindCallback(new OnRebindCallback() {
        @Override
        public boolean onPreBind(ViewDataBinding binding) {
            return super.onPreBind(binding);
        }

        @Override
        public void onCanceled(ViewDataBinding binding) {
            super.onCanceled(binding);
        }

        @Override
        public void onBound(ViewDataBinding binding) {
            super.onBound(binding);
        }
    });

转义字符

android:enabled=”@{value <= min? false:true}”会报错

“&&”转为”&&amp”;
“<” 转为”&lt”;
“>” 转为”&gt”;
<=和>=是什么?

避免死循环

如果几个view对同一个对象的属性都可以操作,且都可以显示,需要避免死循环:

public void setFilterHeight(String filterHeight) {
        if(this.filterHeight.equals(filterHeight))
            return;
        notifyPropertyChanged(BR.filterHeight);
    }

猜你喜欢

转载自blog.csdn.net/lixpjita39/article/details/79330394