MVVM + dataBinding

来源:互联网 发布:淘宝双十一红包口令 编辑:程序博客网 时间:2024/05/17 12:25

MVVM + dataBinding

mvvm模式不做过多讲解,参考下面文章或其他文章对mvvm描述
http://www.jianshu.com/p/6872b699879d

后面又发现一篇比较好的文章,补上
http://lib.csdn.net/article/android/57804?knId=295

引入 dataBinding

按网上部分文章的引入方式,会报如下错误

Error:(2, 1) A problem occurred evaluating project ':mvvm'.> org/apache/commons/lang3/StringUtils

解决办法(基本现在as都是比较高的了,不够高自行升级下)
这里写图片描述
直接就可以引用了

简单示例1

1.布局

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android">    <data>        <variable            name="stu"            type="com.wuhai.mvvm.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>

2.model

package com.wuhai.mvvm;/** * Created by wuhai on 2017/08/14 15:47. * 描述: */public class Student {    private String name;    private String addr;    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 addr;    }    public void setAddr(String addr) {        this.addr = addr;    }}

3.绑定view

package com.wuhai.mvvm;import android.databinding.DataBindingUtil;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import com.wuhai.mvvm.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        setContentView(R.layout.activity_main);        ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);        binding.setStu(new Student("路飞","海贼王"));//model和布局绑定    }}

※ActivityMainBinding这个类是根据布局生成的

运行效果
这里写图片描述

简单示例2
a.传统findViewById +dataBinding
b.imageview绑定
c.修改Model后自动更新UI
1.布局 变化

<?xml version="1.0" encoding="utf-8"?><layout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto">    <data>        <variable            name="stu"            type="com.wuhai.mvvm.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}"/>        <ImageView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            app:photo="@{stu.photo}"/>        <Button            android:id="@+id/btn01"            android:text="更新信息"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <EditText            android:id="@+id/name"            android:layout_width="100dp"            android:layout_height="wrap_content" />        <EditText            android:id="@+id/addr"            android:layout_width="100dp"            android:layout_height="wrap_content" />    </LinearLayout></layout>

a.可以给控件增加id
b.图片要使用自定义属性
2.model

package com.wuhai.mvvm;import android.databinding.BaseObservable;import android.databinding.Bindable;import android.databinding.BindingAdapter;import android.util.Log;import android.widget.ImageView;import com.squareup.picasso.Picasso;/** * Created by wuhai on 2017/08/14 15:47. * 描述: */public class Student extends BaseObservable{    private String name;    private String addr;    private String photo;    public Student(String name, String addr) {        this.name = name;        this.addr = addr;    }    public Student(String name, String addr, String photo) {        this(name,addr);        this.photo = photo;    }    @Bindable    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;        notifyPropertyChanged(BR.name);    }    @Bindable    public String getAddr() {        return addr;    }    public void setAddr(String addr) {        this.addr = addr;        notifyPropertyChanged(BR.addr);    }    public String getPhoto() {        return photo;    }    public void setPhoto(String photo) {        this.photo = photo;    }    @BindingAdapter("photo")    public static void getInternetImage(ImageView iv, String url) {        Picasso.with(iv.getContext()).                load(url).                error(R.mipmap.weixin).                into(iv);    }}

b.@BindingAdapter(“photo”)对于图片加载使用注解
实现静态方法getInternetImage,在生成的ActivityMainBinding里你可以查到关联的iv、并且将来加载的url其实就是getPhoto()返回值
※这里注意一定要加网络权限,毕加索并不会主动告诉你缺少权限的,我都被自己蠢到了
c.类继承BaseObservable,并且name、addr的get方法加上@Bindable注解,set方法实现notifyPropertyChanged(BR.name);
这里新加注解的话记得rebuild一下BR后属性才有
3.绑定view

package com.wuhai.mvvm;import android.databinding.DataBindingUtil;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import com.squareup.picasso.Picasso;import com.wuhai.mvvm.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private Button btn01;    private EditText name;    private EditText addr;    private ActivityMainBinding binding;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        setContentView(R.layout.activity_main);        binding = DataBindingUtil.setContentView(this,R.layout.activity_main);        binding.setStu(new Student("路飞","海贼王","https://www.baidu.com/img/bd_logo1.png"));//model和布局绑定        //取布局id 方式1//        View view = binding.getRoot();//        btn01 = (Button) view.findViewById(R.id.btn01);//        name = (EditText) view.findViewById(R.id.name);//        addr = (EditText) view.findViewById(R.id.addr);        //取布局id 方式2        btn01 = binding.btn01;        name = binding.name;        addr = binding.addr;        btn01.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.btn01:                String nameStr = name.getText().toString().trim();                String addrStr = addr.getText().toString().trim();                //示例 不做效果展示了,这里只是重新绑定model而已//                binding.setStu(new Student(nameStr,addrStr));                //示例2                Student student = binding.getStu();                student.setName(nameStr);                student.setAddr(addrStr);                break;        }    }}

a.binding.getRoot()取得rootview,然后通过findViewById查找控件,后来发现其实有更简单的方法,就是直接binding.控件id
b.图片展示跟之前name、addr一样,绑定model即可
c.我们点击”更新信息”,改变绑定model同时UI也随着变化
运行效果
这里写图片描述

简单示例3
绑定listview
1.布局
activity_list.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <ListView        android:id="@+id/listview"        android:layout_width="match_parent"        android:layout_height="match_parent"></ListView></RelativeLayout>

item_student.xml

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto">    <data>        <variable            name="stu"            type="com.wuhai.mvvm.Student"/>    </data>    <RelativeLayout        android:layout_width="match_parent"        android:layout_height="96dp"        >        <ImageView            android:id="@+id/iv"            android:layout_width="96dp"            android:layout_height="96dp"            android:padding="6dp"            app:photo="@{stu.photo}"/>        <TextView            android:id="@+id/description"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginLeft="8dp"            android:layout_toRightOf="@id/iv"            android:ellipsize="end"            android:maxLines="3"            android:text="@{stu.name}"/>        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="8dp"            android:layout_toRightOf="@id/iv"            android:layout_alignParentBottom="true"            android:layout_marginBottom="2dp"            android:text="@{stu.addr}"            android:textStyle="bold"/>    </RelativeLayout></layout>

布局只绑定item对应的即可,没啥可讲的
2.model 我们使用上面的Student类
3.绑定实现
ListActivity

package com.wuhai.mvvm;import android.content.Context;import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ListView;import java.util.ArrayList;import java.util.List;public class ListActivity extends AppCompatActivity {    private ListView mListView;    private StudentAdapter mAdapter;    public static void startActivity(Context context) {        Intent intent = new Intent(context, ListActivity.class);        context.startActivity(intent);    }    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_list);        mListView = (ListView) findViewById(R.id.listview);        mAdapter = new StudentAdapter(this);        mListView.setAdapter(mAdapter);        initData();    }    private void initData() {        List<Student> datas = new ArrayList<>();        for(int x=0;x<20;x++){            Student student = new Student();            student.setAddr("地址"+x);            student.setName("名字"+x);            student.setPhoto("http://www.lecuntao.com/homenew/templates/default/images/hi.jpg?v=09e9caa5d6");            datas.add(student);        }        mAdapter.setData(datas);    }}

StudentAdapter
我们这里着重看下adapter类,其基类不贴出来了,有兴趣的话直接在最后的git下载来看

package com.wuhai.mvvm;import android.content.Context;import android.databinding.DataBindingUtil;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.wuhai.mvvm.databinding.ItemStudentBinding;/** * Created by wuhai on 2017/08/15 17:40. * 描述: */public class StudentAdapter extends BaseDataAdapter<Student>{    private LayoutInflater inflater;    public StudentAdapter(Context context) {        super(context);        inflater = LayoutInflater.from(context);    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ItemStudentBinding dataBinding;        if (convertView == null) {            dataBinding = DataBindingUtil.inflate(inflater, R.layout.item_student, parent, false);        } else {            dataBinding = DataBindingUtil.getBinding(convertView);        }        dataBinding.setStu(mData.get(position));        return  dataBinding.getRoot();    }}

代码看上去也极其简单
a.ItemStudentBinding根据布局item_student.xml命名生成的binding类;
b.新增DataBindingUtil类,实现convertView的创建和复用;c.dataBinding.setStu(mData.get(position));实现数据UI绑定
运行效果
这里写图片描述

附上github地址(里面东西比较杂,取mvvm这个module即可)
https://github.com/oceanhai/MyFrame.git

待续…

原创粉丝点击