最近项目需要 开始研究MVVM 以前是万年MVC 千年MVP 呵呵 闷骚程序猿自我舒缓

好 刚开始研究
MVVM是将“数据模型数据双向绑定”的思想作为核心,因此在View和Model之间没有联系,通过ViewModel进行交互,而且Model和ViewModel之间的交互是双向的,因此视图的数据的变化会同时修改数据源,而数据源数据的变化也会立即反应到View上。

M 即model 模型
V 即View 视图
VM 即ViewModel 视图模型
 MVVM模式是Model-View-ViewMode模式的简称。由视图(View)、视图模型(ViewModel)、模型(Model)三部分组成。通过这三部分实现UI逻辑、呈现逻辑和状态控制、数据与业务逻辑的分离。
 当然也有很多好处 低耦合 细分工 简介高效
好 今天就说一下 MVVM绑定数据
第一步 准备工作
在app的build.gradle文件里 android{}里添加

dataBinding { 
 enabled = true 
 }

到此 准备工作结束 非常简单
第二步 模型 例如这样 今天绑定数据 textview imgeview 以及刷新
1 textview 非常简单 使用了以后 你绝对不会在想mvc的 findViewById();
我要显示名字和年龄还有性别
student 数据类

private String name; 
 private String sex; 
 private String age; 
 // 构造方法 
 public Student(String name, String sex, String age) { 
 this.name = name; 
 this.sex = sex; 
 this.age = age; 
 }


setget方法自己写 此处就不多说了
mvc 中我们都是以几个布局控件作为根节点 mvvm 中要用layout 作为根节点 同时引用data 标签添加数据类

data/ 
 / variable/ 
 name=”student” 
 type=”com.sxm.mvvmdemo.viewbeans.Student” 
 /variable/ 
 /data 
 LinearLayout 
 android:layout_width=”match_parent” 
 android:layout_height=”match_parent” 
 android:orientation=”vertical”> 
 TextView 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:layout_gravity=”center” 
 android:textSize=”20sp” 
 android:textColor=”#ec4729” 
 android:text=”@{student.name}” 
 TextView 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:layout_gravity=”center” 
 android:textSize=”15sp” 
 android:textColor=”#434542” 
 android:text=”@{student.sex}” 
 TextView 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:layout_gravity=”center” 
 android:textSize=”10sp” 
 android:textColor=”#5ed427” 
 android:text=”@{student.age}” 
 LinearLayout>


好 布局完成 activity中给数据类赋值

@Override 
 protected void onCreate(Bundle savedInstanceState) { 
 super.onCreate(savedInstanceState); 
 final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 
 Student student = new Student(“孙中山”,”男”,”45”); 
 binding.setStudent(student) 
 }


运行一下 就可以显示了
2 点击事件

variable 
 name=”onclick” 
 type=”android.view.View.OnClickListener”/variable> 
 TextView 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:layout_gravity=”center” 
 android:textSize=”20sp” 
 android:onClick=”@{onclick}” 
 android:clickable=”true” 
 android:id=”@+id/name” 
 android:text=”@{student.name}”/> 
 binding.setOnclick(new View.OnClickListener() { 
 @Override 
 public void onClick(View v) { 
 Toast.makeText(MainActivity.this, “点击了”, Toast.LENGTH_SHORT).show(); 
 } 
 });


也可以添加id 进行添加点击事件 可以直接找到这个控件

binding.name.setOnClickListener(new View.OnClickListener() { 
 @Override 
 public void onClick(View v) { 
 Toast.makeText(MainActivity.this, “又点击了”, Toast.LENGTH_SHORT).show(); 
 } 
 });


3 绑定图片

// 图片数据类 
 public class ImgView extends BaseObservable { 
 int picid; 
 @Bindable 
 public int getPicid() { 
 return picid; 
 }
public void setPicid(int picid) {
    this.picid = picid;
    notifyPropertyChanged(BR.picid);
}
@BindingAdapter("android:src")
public static void setPic(ImageView img,int picid){
    img.setImageResource(picid);
}

data> 
 import type=”com.sxm.mvvmdemo.viewbeans.ImgView”>/import> 
 data>


这次我们使用导入的方式 比 / variable/ 还要简洁

ImageView 
 android:id=”@+id/two_img” 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:scaleType=”centerInside” 
 android:clickable=”true” 
 android:onClick=”@{onclickImg}” 
 android:layout_gravity=”center” 
 android:src=”@{imgview.picid}”/>


同上

final ActivityTwoBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_two); 
 final ImgView imgView = new ImgView(); 
 imgView.setPicid(R.drawable.mj12); 
 binding.setImgview(imgView);


运行一下 就可以了
你也可以给他们添加点击事件 同上 一样道理
4 给listview绑定数据

ListView 
 android:layout_width=”match_parent” 
 android:layout_height=”match_parent” 
 android:scrollbars=”none” 
 android:id=”@+id/view_list”>/ListView>


给一个list view

listview = (ListView) findViewById(R.id.view_list);


给数据

lists = new ArrayList<>(); 
 for (int i = 0; i < 20; i++) { 
 ListBean listBean = new ListBean(); 
 listBean.setAge(“17”); 
 listBean.setImgurl(R.drawable.mj12);//图片 
 listBean.setName(“黄渤”); 
 lists.add(listBean); 
 }


重点是listview的item
ListBean 数据类

public class ListBean extends BaseObservable { 
 // 刷新用 
 ObservableField /String> name = new ObservableField<>(); 
 ObservableField / Integer> imgurl = new ObservableField<>(); 
 ObservableField /String> age = new ObservableField<>();
public ListBean() {
}

public ListBean(int imgurl, String name, String age) {
    this.name.set(name);
    this.age.set(age);
    this.imgurl.set(imgurl);
}
//条目点击事件
public void onClickItem(View v){
    Toast.makeText(v.getContext(), "点击了", Toast.LENGTH_SHORT).show();
}

@Bindable
public int getImgurl() {
    return imgurl.get();
}

public void setImgurl(int imgurl) {
    this.imgurl.set(imgurl);
        notifyPropertyChanged(BR.imgurl);
}
// 设置图片
@BindingAdapter("android:src")
public static void setImg(ImageView img, int imgurl){
    img.setImageResource(imgurl);
}

public String getName() {
    return name.get();
}

public void setName(String name) {
    this.name.set(name);
}

public String getAge() {
    return age.get();
}

public void setAge(String age) {
    this.age.set(age);
}
} 
 item xml?xml version=”1.0” encoding=”utf-8”?> 
 layout xmlns:android=”http://schemas.android.com/apk/res/android”> 
 data>
variable
      name="listban"
      type="com.sxm.mvvmdemo.viewbeans.ListBean">/variable>
/data> 
 RelativeLayout 
 android:onClick=”@{listban.onClickItem}” 
 android:gravity=”center_vertical” 
 android:layout_width=”match_parent” 
 android:layout_height=”wrap_content”> 
 ImageView 
 android:layout_width=”80dp” 
 android:layout_height=”80dp” 
 android:scaleType=”centerInside” 
 android:id=”@+id/item_headimg” 
 android:src=”@{listban.imgurl}”/> 
 TextView 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:layout_toRightOf=”@+id/item_headimg” 
 android:layout_alignTop=”@+id/item_headimg” 
 android:layout_marginLeft=”3dp” 
 android:textSize=”15sp” 
 android:textColor=”#fa0d64” 
 android:id=”@+id/item_name” 
 android:text=”@{listban.name}”/> 
 TextView 
 android:layout_width=”wrap_content” 
 android:layout_height=”wrap_content” 
 android:text=”@{listban.age}” 
 android:layout_toRightOf=”@+id/item_headimg” 
 android:layout_below=”@+id/item_name” 
 android:layout_marginTop=”3dp” 
 android:textSize=”13sp” 
 android:id=”@+id/item_age” 
 android:layout_marginLeft=”3dp”/> 
 /RelativeLayout> 
 /layout>

万能adapter

public class MyListviewAdapter /T> extends BaseAdapter { 
 private Context context; 
 private List /T> list; 
 private int layoutId; 
 private int variableId; 
 LayoutInflater inflate;
public MyListviewAdapter(Context context, List /T> list, int layoutId, int variableId) {
    this.context = context;
    this.list = list;
    this.layoutId = layoutId;
    this.variableId = variableId;
    inflate = LayoutInflater.from(context);
}

@Override
public int getCount() {
    return list.size();
}

@Override
public Object getItem(int position) {
    return list.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewDataBinding binding;
    if (convertView==null){
        binding = DataBindingUtil.inflate(inflate,layoutId,parent,false);

    }else {
        binding= DataBindingUtil.getBinding(convertView);
    }
    binding.setVariable(variableId,list.get(position));
    return binding.getRoot();
}


activity
public class ListViewActivity extends Activity {
private ListView listview;
private List<ListBean> lists;
private MyListviewAdapter<ListBean> adapter;
private Handler handler = new Handler(){
    @Override

    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        switch (msg.what){
            case 1:
                Toast.makeText(ListViewActivity.this, "接受了信息", Toast.LENGTH_SHORT).show();
                if (adapter.getCount()==20){
                    for (int i = 0; i < 40; i++) {
                        ListBean listBean = new ListBean();
                        listBean.setAge("18");
                        listBean.setImgurl(R.drawable.mj12);
                        listBean.setName("勃哥");
                        lists.add(listBean);
                    }
                }
                adapter.notifyDataSetChanged();
                break;
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_list_view);
    listview = (ListView) findViewById(R.id.view_list);
    initData();
    adapter = new MyListviewAdapter(ListViewActivity.this,lists, R.layout.list_item, BR.listban);

    listview.setAdapter(adapter);
    listview.setOnScrollListener(new AbsListView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
            Toast.makeText(ListViewActivity.this, "滑动状态变化", Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            Toast.makeText(ListViewActivity.this, "滑动中  "+visibleItemCount, Toast.LENGTH_SHORT).show();
            if (firstVisibleItem+visibleItemCount==totalItemCount&&totalItemCount>0){
                Toast.makeText(ListViewActivity.this, "到底了", Toast.LENGTH_SHORT).show();
               handler.sendEmptyMessage(1);
            }
        }
    });

}

private void initData() {
    lists = new ArrayList<>();
    for (int i = 0; i < 20; i++) {
        ListBean listBean = new ListBean();
        listBean.setAge("17");
        listBean.setImgurl(R.drawable.mj12);
        listBean.setName("黄渤");
        lists.add(listBean);
    }
}

到此 就结束了 mvvm 继续研究 后续发文