开源数据绑定框架android-databinding与google databinding对比

本文对比分析了Android-Databinding和GoogleDatabinding两个开源数据绑定框架,从数据绑定思想、优缺点、具体使用对比等方面进行详细解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开源数据绑定框架android-databinding与google databinding对比

0,前言:

google databinding: 指google 2015 io大会后出的数据绑定框架.
android-databinding: 指 heaven7所出的android开源数据绑定框架。
github地址: https://github.com/LightSun/android-databinding

1, 先说下 数据绑定 (思想都是一样的,类似javaweb数据绑定)。
优点:
1) , 大量减少 findViewById,setBackgroundColor, setImageBitmap,setText,setTextColor 等方法
       的调用。
2), 减轻Activity的代码负担,使得使用者不用复杂的设计模式即可使得代码变得清晰,可读性也很强,
      易于维护。
缺点:
      一旦数据绑定相关的方法名或者字段名修改后,数据绑定配置文件也得跟着修改。
       多牺牲一些内存。

2, 对比google官方的databinding-library

【google databinding 优点】:

  1), 相关的部分代码自动生成(as支持)。 —-> 本框架目前只有简单的as插件

  2), 不需要在layout中定义id(但是由于业务的复杂性,很多地方仍然需要定义id).
  (本框架放置在res/raw目录下。)

  3), 更加丰富的Java表达式的支持。(本框架支持相对弱点,但是足够使用)

google: 所有运算符及嵌套均支持,支持所有java 表达式(除开this,super,new,Explicit generic
             invocation)。支持android资源引用..
本框架:java字段、方法和数组的调用(可嵌套)。以及1次3元运算符(不支持其他运算符,
             如果你非要用建议以静态方法的方式调用 )。亦支持android资源引用.

  4), 相对清晰轻量的架构 。
           google databinding的原代码见:
                         sdk\sources\android-23\android\databinding包。

【Google databinding 缺点】:
1), 数据绑定的配置在对应的layout文件中,会影响布局文件的可读性。尤其的布局复杂之后。
(大家都懂的).

2), 图片边框/圆角/placeholder等不直接支持。

3), 需要手动写RecyclerView等的adapter

【本框架具有,google databinding不具有的】:
1),一般的,不需要你写 listView/GridView/RecyclerView的
adapter.(框架内部自动帮你完成的)

2)更加丰富的事件绑定支持,事件绑定传递自定义参数(包括adapter item事件 绑定).
什么意思呢? Eg:….

3), 图片圆角,边框,圆形等的支持。

3, 具体使用对比(代码)

(1), 基本绑定.
google databinding:

    public class Student {
        private String name;
        private String addr;
        public Student() {
        }
        public Student(String name, String addr) {
            this.name = name;
            this.addr = addr;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAddr() {
            return this.addr;
        }
        public void setAddr(String addr) {
            this.addr = addr;
        }
    }    
    //布局文件如下
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
        <data>
            <variable
                name="stu"
                type="org.loader.androiddatabinding.Student" />
        </data>

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{stu.name}"/>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{stu.addr}"/>
        </LinearLayout>
    </layout>
    //调用代码
    public class MainActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            ActivityMainBinding binding = DataBindingUtil.setContentView(
                    this,R.layout.activity_main);
            binding.setStu(new Student("loader", "干锅排骨"));
        }
    }

Android-databinding :

         //布局文件
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="16dp"
        tools:context=".MainActivity"
        android:orientation="vertical"
        >
        <Button
            android:id="@+id/bt"
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAllCaps="false"
            android:padding="5dp"
            />
 </LinearLayout>

  //数据绑定配置文件
 <DataBinding
    xmlns = "http://schemas.android.com/heaven7/android-databinding/1"
    version="1.0"
    >
    <data>
        <variable name="user"  classname="com.heaven7.databinding.demo.bean.User"  
                  type="bean"/>
        <variable name="mainHanlder"    
               classname="com.heaven7.databinding.demo.callback.MainEventHandler" 
               type="callback"/>
        <import classname="android.view.View" alias="View"/> 
    </data>
    // 绑定文本,文本颜色,背景颜色
    <bind id="bt">
        <property name="text" referVariable="user" >@{user.username}</property>
        <property name="textColor" referVariable="user" >user.male ? {@color/red} 
                      :{@color/random}</property>
        <property name="backgroundColor" referVariable="user" >#00ff00</property>
    </bind>
</DataBinding> 
//调用示例代码:
   DataBinder.getDataBinder(this, R.raw.db_main,false)
             .bind(R.id.bt, true, mUser = new User("heaven7", false));

2), 事件绑定:
google databinding:

     //布局文件
 <layout xmlns:android="http://schemas.android.com/apk/res/android">

   <data>
        <import type="org.loader.app3.EventHandlers" />
        <variable
            name="handlers"
            type="EventHandlers" />
   </data>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CLICK ME"
            android:onClick="@{handlers.handleClick}"/>
    </LinearLayout>
 </layout>
 // 事件处理类
 public class EventHandlers {
    public void handleClick(View view) {
        Toast.makeText(view.getContext(), "you clicked the view", 
                 Toast.LENGTH_LONG).show();
    }
 }

android-databinding:

  //布局文件
   <Button
    android:id="@+id/bt0"
    android:text="@string/change_data_by_handler"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAllCaps="false"
    android:padding="5dp"
    /> 
  //数据绑定配置文件
  <DataBinding
      xmlns = "http://schemas.android.com/heaven7/android-databinding/1"
      version="1.0"
      >
    <data>
        <variable name="user"  classname="com.heaven7.databinding.demo.bean.User"  
             type="bean"/>
        <variable name="mainHanlder"   
             classname="com.heaven7.databinding.demo.callback.MainEventHandler" 
             type="callback"/>
        <import classname="android.view.View" alias="View"/> 
    </data>
    //**绑定的点击事件和长按点击事件**
    <bind id="bt0">
        <property name="onClick" referVariable="user,mainHanlder" >
                   mainHanlder.onClickChangeUsername(user) </property>
        <property name="onLongClick" referVariable="user,mainHanlder" >
               mainHanlder.onLongClickChangeUsername(user)</property>
    </bind>
</DataBinding>

  //调用相关代码 
@DatabindingClass
public class MainEventHandler extends EventContext{

    public MainEventHandler(IDataBinder binder) {
        super(binder);
    }

    @DatabindingMethod
    public void onClickChangeUsername(View v,User user){
        Util.changeUserName(user,"by_MainEventHandler_OnClick");

        //change male
        user.setMale(!user.isMale());
        getDataBinder().notifyDataSetChanged(R.id.bt);
    }

    @DatabindingMethod
    public void onLongClickChangeUsername(View v,User user){
        Toast t =  Toast.makeText(v.getContext(), 
              "------------ onLongClick ---------", Toast.LENGTH_SHORT);
        t.setGravity(Gravity.CENTER, 0, 0);
        t.show();
        Util.changeUserName(user, "by_MainEventHandler_OnLongClick");

        getDataBinder().notifyDataSetChanged(R.id.bt, PropertyNames.TEXT);
    }
}

  DataBinder.getDataBinder(this,R.raw.db_main,false))
            .bind(R.id.bt0, false, mUser,new MainEventHandler(mDataBinder))

3),图片的绑定
Google databinding:

//布局文件:
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <data class=".Custom">
        <variable
            name="imageUrl"
            type="String" />
    </data>
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:image="@{imageUrl}"/>
</layout>
//调用相关代码
public class Utils {
    @BindingAdapter({"bind:image"})
    public static void imageLoader(ImageView imageView, String url) {
        ImageLoaderUtils.getInstance().displayImage(url, 
        );
    }
}
public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            org.loader.app8.Custom binding = DataBindingUtil.setContentView(this,
                    R.layout.activity_main);
            binding.setImageUrl("http://images.youkuaiyun.com/20150810/Blog-       
                   Image%E5%89%AF%E6%9C%AC.jpg");
        }
 }

android-databinding:

 //布局文件    
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.android.volley.extra.ExpandNetworkImageView
        android:id="@+id/eniv2"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        />
 </LinearLayout>

 //数据绑定配置文件
 <DataBinding
 xmlns = "http://schemas.android.com/heaven7/android-databinding/1"
 version="1.0"
 >
    <data>
        <variable name="imageParam"         classname="com.heaven7.databinding.demo.samples.RoundImageBindTest$ImageParam"
            type="bean"/>
        <variable name="eventHandler"               classname="com.heaven7.databinding.demo.samples.RoundImageBindTest$ClickHandler"
            type="callback"/>
        <import classname="com.heaven7.databinding.demo.test.Test" alias="Test"/>
    </data>

    //点击事件, 图片url,圆角,边框,默认图,错误图的配置
    <bind id="eniv2">
        <property name="onClick" referVariable="eventHandler" > 
                   eventHandler.onClickImage()</property>
        <imageProperty type="round" referVariable="imageParam"> 
            <roundSize>{@dimen/corner_size}</roundSize>
            <borderWidth>5dp</borderWidth>
            <borderColor>#ff0000</borderColor>

            <url>imageParam.link</url>
            <default>{@drawable/ic_default}</default>     
            <errorResId>R.drawable.ic_error</errorResId> 
        </imageProperty>
    </bind>
</DataBinding>

//调用相关代码
public class RoundImageBindTest extends BaseActivity {

    @Override
    protected int getBindRawId() {
        return R.raw.db_round_image_test;
    }
    @Override
    protected int getlayoutId() {
        return R.layout.activity_round_image_test;
    }
    @Override
    protected void onFinalInit(Bundle savedInstanceState) {
    }
    @Override
    protected void doBind() {
        mDataBinder.bind(R.id.eniv2, false, new ImageParam(
                 Test.URLS[1]),new ClickHandler(getToaster()) );
    }

    public static class ImageParam{
        float roundSize;
        @DatabindingField
        String url;
        String link;
        public ImageParam(float roundSize, String url) {
            this.roundSize = roundSize;
            this.url = url;
        }
        public ImageParam(String link) {
            this.link = link;
        }
    }
    public static class ClickHandler{

        private final Toaster mToaster;
        public ClickHandler(Toaster mToaster) {
            this.mToaster = mToaster;
        }
        public void onClickImage(View v){
             mToaster.show("---------  onClickImage  ------------");
        }
    }
}

4), ListView / RecyclerView / GridView adapter数据的绑定

Google databinding:

  //item 布局文件
  <layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable
            name="stu"
            type="org.loader.app6.Student" />
    </data>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{stu.name}"
            android:layout_alignParentLeft="true"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(stu.age)}"
            android:layout_alignParentRight="true"/>
    </RelativeLayout>
</layout>

//adapter代码
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private ArrayList<Student> mData = new ArrayList<>();

    private MyAdapter(ArrayList<Student> data) {
        mData.addAll(data);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater
                .from(viewGroup.getContext()), R.layout.item, viewGroup, false);
        ViewHolder holder = new ViewHolder(binding.getRoot());
        holder.setBinding(binding);
        return holder;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.getBinding().setVariable(org.loader.app6.BR.stu,  
                mData.get(i));
        viewHolder.getBinding().executePendingBindings();
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        private ViewDataBinding binding;
        public ViewHolder(View itemView) {
            super(itemView);
        }
        public void setBinding(ViewDataBinding binding) {
            this.binding = binding;
        }
        public ViewDataBinding getBinding() {
            return this.binding;
        }
    }
  }
 //调用主要代码
private RecyclerView mRecyclerView;
private ArrayList<Student> mData = new ArrayList<Student>() {
    {
        for (int i=0;i<10;i++) add(new Student("loader" + i, 18 + i));
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mRecyclerView = (RecyclerView) findViewById(R.id.recycler);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this,
            LinearLayoutManager.VERTICAL, false));
    mRecyclerView.setAdapter(new MyAdapter(mData));
}

android-databinding:

   //item布局文件
   <?xml version="1.0" encoding="utf-8"?>
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
        <com.android.volley.extra.ExpandNetworkImageView
            android:id="@+id/eniv"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:scaleType="centerCrop"
        />

        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="18sp"
            android:padding="10dp"
        />
 </LinearLayout>
 //数据绑定配置文件
 ?xml version="1.0" encoding="utf-8"?>
 <DataBinding
    xmlns = "http://schemas.android.com/heaven7/android-databinding/1"
    version="1.0"
    >
    <data>
        <variable name="imageInfo" 
               classname="com.heaven7.databinding.demo.bean.ImageInfo"  type="bean"/>
        <variable name="itemHandler"           classname="com.heaven7.databinding.demo.samples.ListViewBindAdapterTest$ItemHandler"
            type="callback"/>
    </data>

    <bindAdapter id="rv" referVariable="imageInfo" selectMode="1">
        <item layout="item_image"  referVariable="itemHandler">
            <property name="onClick" >itemHandler.onItemClick()</property>
            <bind id="tv">
                <property name="text" >imageInfo.desc</property>
                <property name="textColor" >imageInfo.isSelected() ?
                             {@color/red} : {@color/random}</property>
                <property name="onClick" >itemHandler.onTextClick()</property>
            </bind>
            <bind id="eniv">
                <property name="img_url" >imageInfo.url</property>
            </bind>
        </item>
    </bindAdapter>
</DataBinding>

//调用主要代码
public class RecycleViewBindAdapterTest extends BaseActivity {

    AdapterManager<ImageInfo> mAM;

    @Override
    protected int getBindRawId() {
        return R.raw.db_test_simple_recycle_view;
    }
    @Override
    protected int getlayoutId() {
        return R.layout.activity_recycle_view;
    }

    @Override
    protected void onFinalInit(Bundle savedInstanceState) {
        RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
        rv.setLayoutManager(new LinearLayoutManager(
                    this,LinearLayoutManager.VERTICAL,false));
    }
    @Override
    public void doBind() {
        List<ImageInfo> infos = new ArrayList<>();
        for(int i=0 , size = Test.URLS.length ; i < size  ;i++){
            infos.add(new ImageInfo(Test.URLS[i],"desc_"+i));
        }
        //ItemHandler 是item的事件处理器
        mAM = mDataBinder.bindAdapter(R.id.rv, infos,
                new ListViewBindAdapterTest.ItemHandler(
                getToaster()));
    }
}
//ItemHandler代码
 public static class ItemHandler {
    private final Toaster mToaster;
    public ItemHandler(Toaster mToaster) {
        this.mToaster = mToaster;
    }

    public void onItemClick(View v, Integer position,ImageInfo item,     
                    AdapterManager<?> am){
        mToaster.show("ItemHandler_onItemClick: position = " +
                        position + " ,item = " + item);
        if(item.isSelected()){
            am.getSelectHelper().setUnselected(position);
        }else{
            am.getSelectHelper().setSelected(position);
        }
    }
    public void onTextClick(View v, Integer position,ImageInfo item, 
                    AdapterManager<?> am){
        mToaster.show("on text click: position = " + position + 
                " ,item = " + item);
    }
}

4, 小结.

个人感觉本框架还是不错的,不过还有些地方待完善。
比如带运算符表达式的支持,代码自动生成(预计后面将会支持)。手势图片(即将支持).
Google毕竟有官方固定的人力支持,而android-databinding目前就1个人负责维护. ~~~~
诚心邀请有意愿想为开源做贡献的朋友来参加,把这个项目做得更好,更完善。

备注: 以上示例
Google databinding主要来自:http://blog.youkuaiyun.com/jdsjlzx/article/details/48133293
Android-databinding 来自: https://github.com/LightSun/android-databinding 的sample
不知道这是什么? 参见我之前写的博客: http://blog.youkuaiyun.com/pkjjun2012/article/details/50286621.
或者直接进入Github ,主页有相关文档(中文版or英文版)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值