MVVM、DataBinding的使用(一)

从MVC—>MVP—>MVVM,框架在不断的转变,接下来介绍MVVM的使用

MVVM 
Model:代表基本的业务逻辑
View:显示内容
ViewModel:将前面两者联系在一起,一个ViewModel和一个View匹配,它没有MVP中的IView接口,而是完全和View绑定,所有View中的修改变化,都会自动更新到ViewModel中,同时ViewModel的任何变化也会自动同步到View上。

DataBinding

在使用MVVM这个框架之前,要先知道DataBinding的基本使用,DataBinding可以将View和一个对象的field绑定,当field更新的时候,framework将收到通知,然后View自动更新。

DataBinding的使用

一、在build.gradle里,像下面这样就设置好了

android{

……

dataBinding {
    enabled = true
}

}

二、布局、代码和运行结果如下:

布局最外围是layout,不再是五大布局,里面是data,variable里 name的名字可以自己随便的取,type是填写bean的包名;布局里有两个TextView, 在text="@{girlFriend.name}" 这个里面通过@{名称.变量名}的方式进行绑定。



    

        

    

    

        

        

    

ActivityMainBinding、DataBindingUtil是自动生成的,不在是setContentView(R.layout.activity_main);而是通过DataBindingUtil.setContentView的方式,将布局放入这个方法,方法内部会遍历这个布局所有的字View元素,达到与数据所对应

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);

        //ActivityMainBinding、DataBindingUtil是自动生成的,不在是setContentView(R.layout.activity_main);而是
        //通过DataBindingUtil.setContentView的方式,将布局放入这个方法内部会遍历这个布局所有的字View元素,达到与
        //数据所对应
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        GirlFriend girlFriend = new GirlFriend();
        girlFriend.name = "Maria";
        girlFriend.country = "外国";
        binding.setGirlFriend(girlFriend);


    }
}

这个是Bean类,类里就两个变量name和country

public class GirlFriend {

    public String name;
    public String country;

}

运行的结果:

MVVM、DataBinding的使用(一)_第1张图片

三、到这里DataBinding的最、最、最基本的用法讲完了,与之前不一样是布局用layout,设置data,通过@{名称.变量名}的方式进行绑定,而代码中不再是通过setContentView而是通过DataBindingUtil.senContentView。从上面可以看到的是代码运行在主线程中,这也很好理解。因为改变UI必须在主线程中,那如果是在子线程中改变UI会怎么样呢?下面是修改过的代码和运行结果:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);

        //ActivityMainBinding、DataBindingUtil是自动生成的,不在是setContentView(R.layout.activity_main);而是
        //通过DataBindingUtil.setContentView的方式,将布局放入这个方法内部会遍历这个布局所有的字View元素,达到与
        //数据所对应
        final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        final GirlFriend girlFriend = new GirlFriend();
        girlFriend.name = "Maria";
        girlFriend.country = "外国";
        binding.setGirlFriend(girlFriend);

        new Thread(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(3000);
                girlFriend.name = "Maria and 罗宾";
                binding.setGirlFriend(girlFriend);

            }
        }).start();


    }
}

MVVM、DataBinding的使用(一)_第2张图片

可以看到是在子线程更新UI居然是可以的!!!至于为什么可以以后会继续讲解DataBinding的原理,上面在子线程更新UI也可以换种写法,首先修改Bean类

Bean类:

public class GirlFriend {

//    public String name;
//    public String country;

    public ObservableField name  = new ObservableField<>();
    public ObservableField country  = new ObservableField<>();

}

Activity中代码修改:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);

        //ActivityMainBinding、DataBindingUtil是自动生成的,不在是setContentView(R.layout.activity_main);而是
        //通过DataBindingUtil.setContentView的方式,将布局放入这个方法内部会遍历这个布局所有的字View元素,达到与
        //数据所对应
        final ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        final GirlFriend girlFriend = new GirlFriend();
        girlFriend.name.set("Maria");
        girlFriend.country.set("外国");
        binding.setGirlFriend(girlFriend);

        new Thread(new Runnable() {
            @Override
            public void run() {
                SystemClock.sleep(3000);
                girlFriend.name.set("Maria and 罗宾");
//                binding.setGirlFriend(girlFriend);

            }
        }).start();


    }
}

不一样的是采用new ObservableField<>()的方式出来变量名,而在子线程中也只要重写设置name名就行,因为使用ObservableField时,更新UI的时候,会去通过framework层去更新UI,所以无需在通过binding.setGirlFriend(),运行结果是一样的,这里不再贴出。

四、实现点击事件,采用@{名称::方法名}或@{名称.方法名}的方式,还是上面的代码修改如下:

布局里:TextView里添加android:onClick="@{girlFriend::ClickOnListener}"进行监听




    

        

    

    

        

        

    

Bean类修改如下,注意的是ClickOnListener方法里要加(View view)不然会报错的,运行结果如下

public class GirlFriend {

//    public String name;
//    public String country;

    private Context mContext;

    public ObservableField name = new ObservableField<>();
    public ObservableField country = new ObservableField<>();

    public GirlFriend(Context context) {
        this.mContext = context;
    }

    public void ClickOnListener(View view) {
        Toast.makeText(mContext, "点击了", Toast.LENGTH_SHORT).show();
    }
    
}

MVVM、DataBinding的使用(一)_第3张图片

五、如果想点击TextView的时候实现TextView的文本内容进行变化,也是可以做到的,还是上面的代码进行修改,如下:

可以直接在Bean类中改,textView.setText("Maria and 罗宾 and 娜美"),运行结果这里就不贴出了。

public class GirlFriend {

//    public String name;
//    public String country;

    private Context mContext;

    public ObservableField name = new ObservableField<>();
    public ObservableField country = new ObservableField<>();

    public GirlFriend(Context context) {
        this.mContext = context;
    }

    public void ClickOnListener(View view) {
        TextView textView = (TextView) view;
        textView.setText("Maria and 罗宾 and 娜美");
        Toast.makeText(mContext, "点击了", Toast.LENGTH_SHORT).show();
    }
}

六、DataBinding用法还有很多,其他的后期继续讲,下面结合MVVM框架来讲解,还是用上面的代码,修改代码如下:

① 类放置结构 创建包mode、view、viewmodle,将类GirlFriend放置到model包中,将MainActivity放置到view中,在包viewmodel中创建MainViewModel类

MVVM、DataBinding的使用(一)_第4张图片

布局代码:在EditText中添加android:addTextChangedListener = "@{ViewModel.accChange}",进行监听文本改变




    
        
    

    
        
        
        

MainViewModel代码:

public class MainViewModel {

    private Context mContext;
    public String acc;
    public String pwt;
    public ObservableField login = new ObservableField<>();

    public MainViewModel(Context mContext) {
        this.mContext = mContext;
        login.set("登陆");

    }

    //进行监听
    public TextWatcher accChange(){
        return new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                acc = s.toString();
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        };
    }

    //进行监听
    public TextWatcher pwtChange(){

        return new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                pwt = s.toString();
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        };
    }

    //登陆监听
    public void loginButton(View view) {
        if (!TextUtils.isEmpty(acc) && !TextUtils.isEmpty(pwt)) {

            Toast.makeText(mContext, "登陆成功", Toast.LENGTH_SHORT).show();

        } else {
            Toast.makeText(mContext, "请输入密码或账号", Toast.LENGTH_SHORT).show();
        }

    }
}

MainActivity代码:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);

        //ActivityMainBinding、DataBindingUtil是自动生成的,不在是setContentView(R.layout.activity_main);而是
        //通过DataBindingUtil.setContentView的方式,将布局放入这个方法内部会遍历这个布局所有的字View元素,达到与
        //数据所对应
        ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        MainViewModel mainViewModel = new MainViewModel(this);
        binding.setViewModel(mainViewModel);

    }
}

运行结果:

MVVM、DataBinding的使用(一)_第5张图片

这么没有用到model包中的类,因为这里只是模仿登陆功能,并不需要用到,后面会讲到,本人小白,若有问题欢迎提出。

微信公众号:猿味生活  欢迎关注,一起成长

 

 

 

 

 

 

你可能感兴趣的:(Android)