Android databinding xml中处理数据与控件绑定

来源:互联网 发布:陈伟霆 知乎 编辑:程序博客网 时间:2024/05/21 17:39

studio对mvvm支持的也在不停的更新,但是还是有些问题没有解决,比如说:

xml中加载图片编译时会爆出警告,xml中设置数据有几种情况没有提示,编译时xml中出现错误并不会定位到错误的位置,等一些问题。

我相信这些问题很快会解决,现如今看mvvm还是很不错的。

我接触和开始使用mvvm是半年多前,当时真的只是为了省略findViewById(哈哈),经过这几个月的项目,慢慢才认识到mvvm的好处。

也踩了不少的坑,下面就记录一下mvvm在xml中绑定数据的几种处理方式。

首先我新建了一个工程在build.gradle中加入:

dataBinding{        enabled = true    }
然后将mainactivity的xml布局修改一下,即在原来最外层的viewgroup外面在套一层<layout></layout>标签,现在布局是这个样子的:

<?xml version="1.0" encoding="utf-8"?><layout xmlns:tools="http://schemas.android.com/tools"    xmlns:android="http://schemas.android.com/apk/res/android">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical"        tools:context="com.xian.ge.myapplication.MainActivity">            </LinearLayout></layout>

这样回到activity中,修改原来的setContentView,变成下面这样:

public class MainActivity extends AppCompatActivity {    private ActivityMainBinding activityMainBinding;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);    }}

解释几句:

上面代码中ActivityMainBinding这个对象是系统帮我们生成的。

例子:如果你的xml名字叫activity_first.xml的话,在你xml包上layout标签的时候就会生成名字叫ActivityFirstBinding的对象。

如果你在activity中找不到的话,那就试着rebuild一下,重新编译一次后就会找到。

下面最后一项准备工作,建一个实体类,这里我就写个简单的用户表,包括了名字,年龄,还有一个布尔的值用来控制是否显示:

/** * 用户信息表 * Created by ge on 2017/5/7. */public class UserEntity {        private String userName;    private int userAge;    private boolean isShow;    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    public int getUserAge() {        return userAge;    }    public void setUserAge(int userAge) {        this.userAge = userAge;    }    public boolean isShow() {        return isShow;    }    public void setShow(boolean show) {        isShow = show;    }}

哦还有一个,我在xml中写几个view,方便下面演示:

<?xml version="1.0" encoding="utf-8"?><layout xmlns:tools="http://schemas.android.com/tools"    xmlns:android="http://schemas.android.com/apk/res/android">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical"        tools:context="com.xian.ge.myapplication.MainActivity">        <TextView            android:id="@+id/tv_user_name"            android:layout_width="match_parent"            android:layout_height="wrap_content" />        <TextView            android:id="@+id/tv_user_age"            android:layout_width="match_parent"            android:layout_height="wrap_content" />        <ImageView            android:id="@+id/iv_user_head"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <Button            android:id="@+id/btn_show"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="年龄段"/>    </LinearLayout></layout>

好了准备工作做完了。大家可以看到上面几个控件我都起好了id。

下面就直接演示mvvm最基本的功能。。。省去了findViewById。

在activity中不用像以前一样先去找到view在进行设置直接用刚才实例化的binding对象就能找到:

 @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);        activityMainBinding.tvUserName.setText("葛大宝");        activityMainBinding.tvUserAge.setText("24岁");        activityMainBinding.btnShow.setText("青少年");    }

是不是很简单。

实际项目中的数据一般都是我们请求拿到之后然后再设置,下面就看看在activity中设置数据变成了什么样子:

1.首先在xml中加入<data>标签:


<?xml version="1.0" encoding="utf-8"?><layout xmlns:tools="http://schemas.android.com/tools"    xmlns:android="http://schemas.android.com/apk/res/android">    <data>        <variable            name="userInfo"            type="com.xian.ge.myapplication.UserEntity"/>    </data>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical"        tools:context="com.xian.ge.myapplication.MainActivity">        <!-- 节省地方省略其中控件,文章上面有 -->    </LinearLayout></layout>

这样就直接在activity中设置数据了,如下:

@Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);        // 模拟拿到数据        UserEntity userEntity = new UserEntity();        userEntity.setUserName("葛大宝1");        userEntity.setShow(false);        userEntity.setUserAge(24);        // 设置到xml中显示        activityMainBinding.setUserInfo(userEntity);    }

设置了之后我们就要回到xml中进入今天正题:

1.首先显示名字:

<TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="@{userInfo.userName}"/>

这是最简单的直接@符号加{},中间用上面引入的数据对象设置即可。

2.控制button的显示或隐藏:

因为涉及到View的使用,所以要在data中引入View:

 <data>        <import type="android.view.View"/>                <variable            name="userInfo"            type="com.xian.ge.myapplication.UserEntity"/>    </data>

这时候就可以直接使用了:

 <Button            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="年龄段"            android:visibility="@{userInfo.show ? View.GONE : View.VISIBLE}"/>

大家看到这是用布尔类型来判断,但是实际项目中不可能全是这么简单的判断条件,可能需要通过一个int类型或者string类型来判断,

那么这时候就涉及到了引入外部工具类来帮助我们处理这个数据。

加入现在我们的判断规则是,根据年龄来控制按钮的显隐性,年龄大于五十岁的隐藏,小于五十岁的显示,

那么首先我新建一个工具类:

/** * 工具类 * Created by ge on 2017/5/7. */public class DataUtils {        public static boolean isShow(int age){        return age < 50;    }}

在xml中引入工具类:

<data>        <import type="android.view.View"/>        <import type="com.xian.ge.myapplication.DataUtils" alias="dataUtils"/>                <variable            name="userInfo"            type="com.xian.ge.myapplication.UserEntity"/>    </data>

大家看到我给工具类设置了一个别名,下面view中使用别名即可:

 <Button            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="年龄段"            android:visibility="@{dataUtils.isShow(userInfo.userAge) ? View.GONE : View.VISIBLE}"/>

3.基础类型引用

换一个场景,现在我的一个textView要显示年龄,但是年龄是int类型,这时候根在class中没啥区别:

<TextView            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="@{String.valueOf(userIfo.userAge)}"/>

像string,int, float等是不需要像上面使用View一样在data中import进来的。


4.图片的设置

新建图片加载工具类:

/** * 图片加载 * Created by ge on 2017/5/5. */public class ImageLoadViewModel {        @BindingAdapter({"bind:testState"})    public static void loadChildStateImg(ImageView view, String path){        Glide.with(view.getContext()).load(path)                .placeholder(path)                .into(view);    }}

在xml中使用:

 <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            app:testState="@{"图片路径"}"/>

参数传的string,是图片的路径。

实际项目中也可能给你的不是个路径,而是根据类型加载不同的图片,也可能是本地图片,那么下面看下。

加载图片的工具方法换成:

 @BindingAdapter({"bind:testState"})    public static void loadChildStateImg(ImageView view, int type){                if (type == 1){            Glide.with(view.getContext()).load(path)                    .placeholder(path)                    .into(view);        }else {            Glide.with(view.getContext()).load(path)                    .placeholder(path)                    .into(view);        }    }
加载图片按照上述写法,编译的时候会爆一个警告,不要理他。



先记录到这,只写了一些基本的用法,mvvm还有很多牛逼的地方,慢慢来。

如果你项目已经写好了,想试试也没关系,从最简单的findViewById开始。





0 0
原创粉丝点击