全新DBinder双向数据绑定框架,使用编译时注解处理。

来源:互联网 发布:数组下边标为什么是-1 编辑:程序博客网 时间:2024/05/17 13:41

转载请注明出处:
http://blog.csdn.net/liu470368500/article/details/49646683

前段时间,写过一篇基本的DBinder,但是呢。在写完之后不久。就发现虽然当时自己感觉很爽。但是用起来非常蛋疼的一点。就是每个绑定单元都非常难写!数据绑定本身的作用就是让猿们好编写,代码看起来可读性强,这与初衷就不符了。所以呢。终于在抽时间花了大力气之后。出了这篇新的数据绑定。只要一行简单的注解就可轻松的绑定特定数据与View了!

下面来看个简单的样例:

public class User {    @Bind(view = R.id.tv_username, clz = TVUnit.class)    private String username;    @Bind(view = R.id.tv_password, clz = TVUnit.class)    private String password;    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }}

这是个普通的bean.里面一个username.一个password,与普通的bean不同之处在于。加了个Bind注解而已。然后看看Activity中的代码:

public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        User user = User_Bind.attach(getWindow().getDecorView());        user.setUsername("This is username");        user.setPassword("This is password");    }}

其中有一个User_Bind类。调用它的attach方法生成一个user对象。这个对象就是db对象了,User_Bind类就是我们根据User中的Bind注解生成的java类。这样我们就能直接通过User对象直接对界面上View进行更新了。下面是运行图

这里写图片描述

这就是关于DBinder的最简单用法。从这里看。和上篇的除了在bean的写法上面有所不同外。其他基本一致。当然DBinder还提供另一种用法。在某些时候。我们可能需要在不同界面间进行界面数据更新。就用写这个例子来举例。A界面有username,password,那么我跳转到B界面。修改username.password之后。回到A后A也能自动绑定到最新的用户信息并显示。

在此之前。先介绍一下关于生成的java类User_Bind类。这个类的生成就是依靠的使用有Bind注解的bean对象来生成。类名统一为XXX_Bind,此类提供的除重写的父类的带Bind注解的字段的set/get方法外。还提供额外的几个方法提供调用。方便开发者使用:

  • getXXXUnit():获取Bind属性中绑定的clz对象。比如此例中的TVUnit。就是专用于绑定TextView的文字显示的。获取到此对象后。即可很方便的取出各种绑定数据及自行解绑数据
  • attach(root):此方法在上例中已经用到。传入一个根布局。通过此根布局在内部进行View绑定。
  • detach(bean):对绑定类进行解绑。调用此方法会通知到bean中Bind注解调用到的单元绑定类的如TVUnit的detach方法。方便回收资源
  • castToBean(bean):将绑定类转换成基本的bean。

要在多页面进行数据更新。常规做法是做一个DataManager来管理多页面数据。我们这里先不用此方式来写。先提供一种懒人的写法。使用User类的static实例。也能保证不会内存泄漏。

public static User user;    @Override    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {        super.onCreate(savedInstanceState, persistentState);        setContentView(R.layout.activity_main);    }    @Override    protected void onStart() {        // 此处当首次进入后。user为空。进行的操作相当于attach.        // 当再次进入时。user不为空。即将user中的信息复制到新的绑定类中并返回        user = User_Bind.rebind(getWindow().getDecorView(),user);        super.onStart();    }    @Override    protected void onDestroy() {        // 将绑定类User_Bind实例user转换为子类User bean实例。并保存,方便下次进入页面时重新绑定数据        // 解绑原先的绑定类。解绑时会通知到绑定单元类如此处使用的TVUnit中的detach方法,方便进行资源回收        User temp = User_Bind.castToBean(user);        User_Bind.detach(user);        user = temp;        super.onDestroy();    }

当然此种用法完全不推荐。用在这只是提供一个懒人方案而已。数据都应该写有一个专有的数据管理器来统一管理:

public class DataManager {    User user;    public User getUser() {        return user;    }    public void setUser(User user) {        this.user = user;    }    private static DataManager ourInstance = new DataManager();    public static DataManager getInstance() {        return ourInstance;    }    private DataManager() {    }}

然后在Activity中进行相关配置:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }    @Override    protected void onStart() {        user = User_Bind.rebind(getWindow().getDecorView(),user);        super.onStart();    }    @Override    protected void onPause() {        DataManager.getInstance().setUser(User_Bind.castToBean(user));        super.onStop();    }    @Override    protected void onDestroy() {        User_Bind.detach(user);        user = null;        super.onDestroy();    }

这样。当你在别的任意页面。对DataManager中的User数据进行修改之后。回到界面就都能显示回最新的数据于界面上了。

使用方式:

  • eclipse:demo中libs下有三个jar,DBinder.jar.DBinderProc.jar,JavaPoet.jar。将这三个放入项目中。进入属性设置页。找到左侧Java compile栏:

    这里写图片描述

将三个jar加入列表。这样每次一代码一保存就会自动编译生成相应的java文件:
这里写图片描述

  • android studio:将jar包同样引用libs.根build.gradle中加入:
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.2'

在要使用的module中build.gradle上加入

apply plugin: 'android-apt'

github地址
demo地址

5 0