Android MVVM模式下DataBinding的基本使用

Android app开发模式 同时被 3 个专栏收录
1 篇文章 0 订阅
5 篇文章 0 订阅
6 篇文章 0 订阅

Android MVVM模式下DataBinding的基本使用

1. 说到MVVM模式呢,就不得不提一下Android 另外两个App的设计架构:MVC和MVP模式。

2. 但我们这节的中心思想还是要着重讲解一下DataBinding这个架构;一开始用它的时候呢可能觉得不太习惯,在布局里各种添加比较麻烦,但是用起来之后呢,却发现在Activity里省了很多代码。

3. 他的书本概念是这样的:DataBinding是一个实现数据和UI绑定的框架,是实现MVVM模式的工具,而MVVM中VM(ViewModel)和View可以通过DataBinding来实现数据绑定。明白没?是不是有点小懵,没关系,然并卵,很简单,就是说,我们的布局层和数据层不用在每个控件findViewById或一些插件来绑定了,直接用DataBinding一起绑定上就可以了(DataBinding在xml要直接关联数据源下节讲这个)!

**4.DataBinding的数据绑定又分为单项绑定和双向绑定@{}和@={},实现数据的监控变化,实时更新 **

好废话说多了,直接上代码!!!

4. 在app下build里添上这两句代码(引用)

android {
    compileSdkVersion 28
    
    dataBinding {
        enabled = true
    }

5. 再从布局里加上layout标签

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="presenter"
            type="com.medical.Presenter_Base" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bei"
        android:orientation="vertical">

            <LinearLayout
                android:id="@+id/main_data"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/white"
                android:orientation="vertical">

                <WebView
                    android:id="@+id/webView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />

            </LinearLayout>
    </LinearLayout>
</layout>

6. 在上图中我们看到了一个Presenter_Base类,那它是在哪来的呢,当然是自己写的了啦。(绑定)

public class Presenter_Base {
    public Activity activity;
    public ViewDataBinding binding;
    public Fragment fragment;

    public Activity getActivity() {
        return activity;
    }

    public void setActivity(Activity activity) {
        this.activity = activity;
    }

    public ViewDataBinding getBinding() {
        return binding;
    }

    public void setBinding(ViewDataBinding binding) {
        this.binding = binding;
    }

    public Fragment getFragment() {
        return fragment;
    }

    public void setFragment(Fragment fragment) {
        this.fragment = fragment;
    }

    public void clickItems(View view){}
}

7. 继承

public class Presenter_Main extends Presenter_Base {
    public Presenter_Main(Activity activity) {
        this.activity=activity;
    }

    @Override
    public void clickItems(View view) {
        switch (view.getId()){
        }
    }
}

8. 绑定

public class Activity_Shop_News extends Activity_Base {

    //    布局文件(DataBinding 绑定布局)
    private ActivityShopNewsBinding binding;

    private Presenter_Main presenter;

    private Context context;

    @Override
    protected void initViews(Bundle savedInstanceState) {
        binding = DataBindingUtil.setContentView(this, R.layout.activity_shop_news);
        presenter = new Presenter_Main(this);
        binding.setPresenter(presenter);
        this.context = this;
    }

    @Override
    protected void initListener() {
//     (直接点出控件ID)
        binding.linearReturn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    @Override
    protected void initData() {

    }
}

9. 我们可以看到上图代码中 布局的名字和引用DataBinding(绑定布局)的名字是一样的只不过去掉了下划线然后首字母大写了;这是因为DataBinding是根据你布局的名字来生成布局Binding类的。

10. 下面我们看一下xml中的具体写法及与实体类的操作。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <!--DataBinding的配置文件-->
    <data>
        <!--name属性相当于声明了一个全局属性、type指定name对应的具体的数据类或是MVVM中VM-->
        <variable
            name="userInfo"
            type="com.example.anctvity_databinding.UserInfo" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="50dp">

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={userInfo.userName}" />

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={userInfo.passWord}" />
            
       <ImageView
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:imageUrl="@{@string/url}"
            app:placeHolder="@{@drawable/holder}"
            app:error="@{@drawable/error}" />

        <View
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</layout>

public class UserInfo {

    public ObservableField<String> userName = new ObservableField<>();
    public ObservableField<String> passWord = new ObservableField<>();

    public String getName() {
        return name;
    }

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

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getContest() {
        return contest;
    }

    public void setContest(String contest) {
        this.contest = contest;
    }

    private String name;

    private String data;

    private String contest;

}

我们不需要setContentView(),取而代之使用DataBindingUtil.setContentView(),返回的ActivityMainBinding这个类不需要我们创建,DataBinding这个库自动帮我们创建,命名规则就是layout文件首字母大写+Binding:

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding binding;

    private UserInfo userInfo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        userInfo = new UserInfo();
        userInfo.userName.set("enssi");
        userInfo.passWord.set("xinxibu");
        binding.setUserInfo(userInfo);
    }

//    适配器中
    @BindingAdapter({"app:imageUrl", "app:placeHolder", "app:error"})
    public static void loadImage(ImageView imageView, String url, Drawable holderDrawable, Drawable errorDrawable) {
        Glide.with(imageView.getContext())
                .load(url)
                .placeholder(holderDrawable)
                .error(errorDrawable)
                .into(imageView);
    }
}

<?xml version="1.0" encoding="utf-8"?>
<layout <?xml version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">

<data>
        <variable
            name="activity"
            type="com.example.databinding.MainActivity" />

        <variable
            name="testBean"
            type="com.example.databinding.TestBean" />

        <import type="android.view.View" />
</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/colorWhite"
    android:gravity="center_vertical">

    <LinearLayout
        android:id="@+id/layout_home"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_weight="1"
        android:orientation="vertical"
        android:onClick="@{click.onClick}">

        <ImageView
            android:id="@+id/img_home"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:src='@{testBean["imgid"]}'
            bind:imageUrl="@{imageUrl}"/>

        <TextView
            android:id="@+id/text_home"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/VillageTextTheme"
            android:text="@string/home_home"
            android:textColor='@{testBean["textColor"]}'/>

    </LinearLayout>

     <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:gravity="center"
            android:orientation="vertical"
            android:visibility="@{testBean.progress?View.INVISIBLE:View.VISIBLE}">

            <ImageView
                android:id="@+id/none_data"
                android:layout_width="345dp"
                android:layout_height="180dp"
                android:scaleType="fitCenter"
                android:src="@{testBean.emptyIconRes}"/>


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="25dp"
                android:layout_below="@+id/none_data"
                android:layout_centerHorizontal="true"
                android:text="@{testBean.currentStateLabel}"
                android:textSize="16sp"/>


        </LinearLayout>
    </LinearLayout>
</layout>

总结:DataBinding是一个实现数据和UI绑定的框架,同时也是实现MVVM模式所依赖的工具,而且可以直接在xml中绑定数据并实现一些处理逻辑,实时动态刷新数据,它的功能强大,可以节省很多手写的代码,而且性能也很好;缺点的话呢:个人认为调试比较繁琐和提示比较不太智能以外其他的都还好。

好了,故事到这里就结束了,让我们明年同一时间再会!!!

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值