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

来源:互联网 发布:象过河进销存软件 编辑:程序博客网 时间:2024/06/05 06:49

开源数据绑定框架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>  //调用相关代码 @DatabindingClasspublic 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.csdn.net/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));    }};@Overrideprotected 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.csdn.net/jdsjlzx/article/details/48133293
Android-databinding 来自: https://github.com/LightSun/android-databinding 的sample
不知道这是什么? 参见我之前写的博客: http://blog.csdn.net/pkjjun2012/article/details/50286621.
或者直接进入Github ,主页有相关文档(中文版or英文版)

1 0
原创粉丝点击