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

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开始。





发布了73 篇原创文章 · 获赞 59 · 访问量 33万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览