MVVM + dataBinding
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 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
待续…
更多相关文章
- android 在当前的布局上加载xml填充内部
- android:DataBinding使用小结(一)
- 解决聊天页面解决软键盘遮挡住输入框,和输入法把整个页面顶上去的
- Android(安卓)基础知识之JobScheduler基本使用
- 认识 Android(安卓)Service
- cocos2dx中利用xcode 调用java中的函数
- android中listView如何复用多种布局
- android baseadapter的getview调用两次
- ArcGIS for Android示例解析之GP服务调用-----ViewShed