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);
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setStu(new Student("路飞","海贼王"));
}
}
※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);
binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setStu(new Student("路飞","海贼王","https://www.baidu.com/img/bd_logo1.png"));
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();
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
待续…
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)