Giter Site home page Giter Site logo

mvvmdemo's Introduction

MVVM

MVVM是什么?

MVVM它分为三个层:

  • Model:数据模型,对数据进行处理
  • View:UI展示,包括Activity、Fragment等
  • ViewModel:View和Model之间的桥梁,处理界面逻辑,让View和Model之间进行交互。 这里写图片描述

为什么要有MVVM?

现在使用的基本是MVP或是MVC,最开始觉得MVP已经很好了,因为它通过Presenter把View和Model分隔开来,很大程度减低耦合性。但是慢慢发现MVP也存在着它的不足:

  • 接口多,而且粒度不好控制,分太小接口会很多,分太大代码又会很多。
  • View层上的某个UI可能变更,数据映射到UI上可能也要跟着改变
  • P层可能会随着业务的增多而代码变多,View的方法也可能变多。这可能会导致他们依然会产生臃肿。 而MVVM的特点就是:
  • 可重用性:View的视图逻辑放在ViewModel中,多个View可重用这些视图逻辑
  • 双向绑定:可直接在布局中填充数据,而不用去获取View的实例再去setter。

说到MVVM,当然少不了DataBinding

介绍

DataBinding是谷歌提供的一个框架,它让我们省去了许多findViewById和View设置数据的操作。

使用

  • 在build.gradle文件中的android下添加dataBinding{enabled=true}
  • 准备好数据模型:
public class User extends BaseObservable{
    private String name;
    private int arg;

    public User(String name, int arg) {
        this.name = name;
        this.arg = arg;
    }
    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);

    }
    @Bindable
    public int getArg() {
        return arg;
    }

    public void setArg(int arg) {
        this.arg = arg;
        notifyPropertyChanged(BR.arg);
    }
}

加上注解和notifyPropertyChanged(BR.xxx)是为了绑定的实体改变时布局中的数据跟着改变,还有另一种更方便的

public class Other {
    //效果和User的@Bindable+notifyPropertyChanged(BR.xxx)相同
    //通过set改变数据进而布局中绑定的数据跟着改变
    public final ObservableField<String> name = new ObservableField<>();
    public final ObservableField<Integer> age = new ObservableField<>();
}

  • 在布局文件中绑定数据
<layout xmlns:android="http://schemas.android.com/apk/res/android">
//在layout标签中导入User
<import
    alias="aUser" <!—别名,防止类名重复-- >
    type="com.sendi.mvvmdemo.bean.User"/>
<variable
    name="user"
    type="aUser"/>
	//绑定数据:
	<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:gravity="center"
    android:text="@{user.name}" <!—绑定User类的name属性 -- >
    android:textColor="#000000"
    />
</layout>
  • 绑定点击事件 Java代码
public class MyClick {
    public void onChangeAge(View view){//次点击方法必须是public void 并且参数为View
        Toast.makeText(view.getContext(), "click me!", Toast.LENGTH_SHORT).show();
    }
}

布局文件

<variable
    name="myClick"
    type="com.sendi.mvvmdemo.MyClick"/>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="changeAge"
    android:onClick="@{myClick.onChangeAge}"
    />

  • 图片的显示 Java类
public class ImageUtil {
//此方法要static,上边主节点参数为布局文件中的属性(第二个参数可换成别的类型)
    @BindingAdapter({"image"})
    public static void imageLoader(ImageView imageView,int imageId){
        imageView.setImageResource(imageId);
    }
}

布局文件中

<ImageView
    android:layout_width="60dp"
    android:layout_height="60dp"
    image="@{imgId}"
    />

接下来是设置绑定
  • 数据显示
//获取Binding
ActivityMainBinding mBinding
		=DataBindingUtil.setContentView(this,R.layout.activity_main);
//设置要显示的数据实体
User mUser= new User(”asendi”,21)  
mBinding.setUser(mUser);

这样数据就显示到界面中。

  • 动态改变数据
mUser.setAge(22);
//只要修改User对象,此时界面会跟着改变年龄的显示
  • 点击事件
mBinding.setMyClick(new MyClick());
//这样点击事件便失效了
  • 设置图片
mBinding.setImgId(R.mipmap.bg);//设置图片资源
  • 列表
    • 这里用RecyclerView为例子,在布局中的RecyclerView与往常一样
mBinding.recyclerView //这样便是获取到RecyclerView的实例,而不需要去FVB;其中recyclerView是在布局中的id

item布局文件:

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable
            name="user"
            type="com.sendi.mvvmdemo.bean.User"/>
    </data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
<TextView
    android:id="@+id/name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@{user.name}"
    />
    <TextView
        android:id="@+id/age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@{user.age}"
        />
</LinearLayout>
</layout>

适配器:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder> {
    private List<User> mUserList = new ArrayList<>();

    public MyAdapter() {}

    public void refresh(List<User> userList) {
        mUserList = userList;
        notifyDataSetChanged();
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return MyHolder.create(
                LayoutInflater.from(parent.getContext()),parent);
    }

    @Override
    public void onBindViewHolder(MyHolder holder, int position) {
        holder.bindTo(mUserList.get(position));
    }


    @Override
    public int getItemCount() {
        if (mUserList==null)
            return 0;
        return mUserList.size();
    }

    static class MyHolder extends RecyclerView.ViewHolder {

        private UserItemBinding mItemBinding;

        public MyHolder(UserItemBinding binding) {
            super(binding.getRoot());
            this.mItemBinding = binding;
        }

        public void bindTo(User user){
            mItemBinding.setUser(user);//将数据设置到布局文件中
            mItemBinding.executePendingBindings();//强行绑定数据

        }

        static MyHolder create(LayoutInflater inflater, ViewGroup parent) {
            UserItemBinding binding =		//获取一个item布局文件的Binding
                    UserItemBinding.inflate(inflater, parent, false);
            return new MyHolder(binding);
        }
    }
}

在布局文件中还支持的表达式

  • 数学表达式:+=*/
  • 字符串拼接:+
  • 逻辑表达式:&& ||
  • 位操作符:^ | &
  • 一元操作法:+-!~
  • 位移操作符:>> << >>>
  • 比较操作符:== > >= < <=
  • instanceof
  • 分组操作符:()
  • 强转、方法调用
  • 字面量:character、String、numeric、null
  • 字段的访问:User.name
  • 数组
  • 三元操作符:? :

以上便是浅浅的总结,希望可以指出不足之处,谢谢。

mvvmdemo's People

Contributors

asendilin avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.