MVVM + dataBinding

2023-05-16

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<Student> 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

待续…

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MVVM + dataBinding 的相关文章

  • 如何将 DataTable/DataSet 转换为 ObjectDataSource

    我有一个与 ObjectDataSource 绑定的 GridView 我有一个返回数据表的方法 如何将 DataTable 提供给 ObjectDataSource 以便在代码中更新 GridView Example protected
  • 第一次调用后 LiveData 未观察到

    我实现了 LiveData 和 ViewModel 来模仿 AsyncTaskLoader 我从 DCIM 中的相机目录加载文件名 然后附加一个 fileObserver 来观察删除文件 图片 时的情况 然后回调告诉 LiveData 在发
  • 如何在代码中访问 DataGridCell 的数据对象?

    基本上 我已经绑定了数据网格 使其类似于科目时间表 每行代表一个学期的科目 该学期内的每个单元格代表一个科目 我现在尝试添加拖放功能 以便您可以将其他主题拖到网格上 这将更新底层数据结构 我可以使用一些可视化树方法来查找用户将新主题拖动到的
  • LiveData无法观察到变化

    我正在更新一个ViewModel 中 DialogFragment 的 LiveData 值 但无法获取Fragment中的值 视图模型 class OtpViewModel private val otpUseCase OtpUseCas
  • 将 dataGridView 绑定到绑定列表并按文本框过滤行

    我正在开发一个 Winforms 应用程序 并且有一个已经绑定到 dataGridView 的对象的 BindingList 我还有一个 过滤器 文本框 如果它们与文本框文本不匹配 我想从 datagridview 行中过滤掉行 我想以某种
  • 使用 MVVM 在 WPF 中打印 TreeView

    我有一个树视图来从文本文件返回文本搜索结果
  • 数据绑定的 IntelliSense 不起作用

    经过几个小时尝试调试由错误的属性引起的数据绑定问题Binding扩大 一旦我注意到这个错误 我就会意识到如果 IntelliSense 可用 我可能一开始就不会犯这个错误 作为一个习惯在错误输入名称时出现错误 警告的 Visual Stud
  • 当 ToString() 具有协作对象时,为什么 WPF 数据绑定不显示文本?

    在一个简单的形式中 我绑定到许多不同的对象 有些放在列表框中 有些放在列表框中 有些放在列表框中 一些在文本块中 其中一些对象具有协作对象 在这些对象上ToString 方法在执行其工作时调用 通常是某种格式化程序 当我单步执行代码时 我发
  • 禁止/阻止选择 wpf 中禁用的组合框项目

    我正在编写一个应用程序 其中我想禁用其中的一些项目ComboBox并且还想禁止 阻止选择禁用的项目 请注意ComboBox在主窗口中有另一个 ComboBox 作为 ComboBox Item init 在运行时由DataTemplateS
  • 如何从 silverlight 中的视图模型从一个视图导航到另一个视图?

    我有一个 ViewModel 和两个 View 如何从 ViewModel 导航到 View2 我在某处读到我们需要使用 PRISM 在 Silverlight 中从 ViewModel 打开多个视图 PRISM 有什么替代方案吗 理想情况
  • 当 QML 对象不可见时防止 QML 属性绑定?

    我正在开发一个具有大量属性绑定的 QML 应用程序 数百个对象被跟踪并以不同的形式显示 例如 Qt3D QCanvas 当我在应用程序的单独页面上时 x y 位置和相对大小的属性绑定仍在发生 我怎样才能阻止他们 我知道我可以根据属性是否可视
  • WPF MVVM 在窗口关闭时调用 ViewModel Save 方法

    我已经弄清楚如何从我的 ViewModel 关闭窗口 现在我需要从另一侧解决窗口关闭问题 当用户单击窗口的关闭按钮时 我需要在 ViewModel 中触发 Save 方法 我正在考虑将 Command 属性绑定到 Window 的关闭事件
  • 如何在 MVVM 中使用应用程序命令

    我想使用 ApplicationCommands Cut 复制 粘贴 保存 它们看起来很有趣 因为命令路由 键绑定以及某些控件使用它们的事实 我了解如何绑定到虚拟机上的中继 委托命令 但我似乎无法理解应用程序命令 我找到了一些旧的答案 但没
  • MVVM ViewModel 与 MVC ViewModel

    ViewModel 是一个在 MVVM Model View ViewModel 和 ASP NET MVC 的推荐实现中使用的术语 鉴于每种模式都使用相同的术语 研究 ViewModel 可能会令人困惑 MVC ViewModel 和 M
  • 如何在WPF中使用一次性视图模型?

    如果视图模型引用非托管资源或具有事件处理程序 例如调度程序计时器上的处理已过去 如何确保视图模型得到正确处理 在第一种情况下 终结器是一种选择 虽然并不理想 但在后者中 它永远不会被调用 我们如何判断何时不再有视图附加到视图模型 我通过执行
  • 如何创建自动滚动文本框

    我有一个 WPF 应用程序 其中包含一个多行文本框 用于显示调试文本输出 如何设置文本框 以便将文本附加到框中时 它会自动滚动到文本框的底部 我正在使用 MVVM 模式 理想情况下 纯 XAML 方法会很好 TextBox 本身不一定是焦点
  • 如何在Android中的DataBinding的ViewModel类中获取R.string

    我目前正在使用databinding对于我的 Android 应用程序项目 我想设置error留言在我的CustomTextView from R string txtOldPassWordError并从另一个名为的类中进行设置ViewMo
  • 如何使用 ViewModel 对 silverlight 数据网格实现自然(人类字母数字)排序?

    在使用数据网格的 silverlight 项目中 我使用一些定义 标签编号 的列 它是一个 Varchar 我想按照自然排序顺序对此列进行排序 如中所述 http www interact sw co uk iangblog 2007 12
  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • ComboBox DataBinding 导致 ArgumentException

    我的几个类对象 class Person public string Name get set public string Sex get set public int Age get set public override string

随机推荐

  • 从Trie树(字典树)谈到后缀树(10.28修订)

    从Trie树 xff08 字典树 xff09 谈到后缀树 说明 xff1a 本文基本上是 整理 性质 xff0c 致谢文末的参考文献 引言 常关注本blog的读者朋友想必看过此篇文章 xff1a 从B树 B 43 树 B 树谈到R 树 xf
  • 编程艺术第二十三~四章&十一续:杨氏矩阵查找,倒排索引关键词Hash编码

    第二十三 四章 xff1a 杨氏矩阵查找 xff0c 倒排索引关键词Hash不重复编码实践 作者 xff1a July yansha 编程艺术室出品 出处 xff1a 结构之法算法之道 前言 本文阐述两个问题 xff0c 第二十三章是杨氏矩
  • 如何用Axure的rp8版本做一个好看小程序的原型

    最近公司要做一个小程序 xff0c 抽空研究了一下Axure的各项功能发现挺简单的 xff0c 原型效果如下 xff0c 项目的文件可以点击下载 准备工具 Axure rp8 xff0c 点击下载 微信小程序元件库 xff0c 点击下载 安
  • 教你如何迅速秒杀掉:99%的海量数据处理面试题

    教你如何迅速秒杀掉 xff1a 99 的海量数据处理面试题 本文经过大量细致的优化后 xff0c 收录于我的新书 编程之法 xff1a 面试和算法心得 第六章中 xff0c 新书目前已上架 京东 当当 作者 xff1a July 出处 xf
  • 从决策树学习谈到贝叶斯分类算法、EM、HMM

    从决策树学习谈到贝叶斯分类算法 EM HMM 引言 最近在面试中 xff0c 除了基础 amp 算法 amp 项目之外 xff0c 经常被问到或被要求介绍和描述下自己所知道的几种分类或聚类算法 当然 xff0c 这完全不代表你将来的面试中会
  • 支持向量机通俗导论(理解SVM的三层境界)

    支持向量机通俗导论 xff08 理解SVM的三层境界 xff09 作者 xff1a July 致谢 xff1a pluskid 白石 JerryLead 说明 xff1a 本文最初写于2012年6月 xff0c 而后不断反反复复修改 amp
  • 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    从K近邻算法 距离度量谈到KD树 SIFT 43 BBF算法 前言 前两日 xff0c 在微博上说 xff1a 到今天为止 xff0c 我至少亏欠了3篇文章待写 xff1a 1 KD树 xff1b 2 神经网络 xff1b 3 编程艺术第2
  • 程序员编程艺术第三十~三十一章:字符串转换成整数,通配符字符串匹配

    第三十 三十一章 xff1a 字符串转换成整数 xff0c 带通配符的字符串匹配 前言 之前本一直想写写神经网络算法和EM算法 xff0c 但写这两个算法实在需要大段大段的时间 xff0c 而平时上班 xff0c 周末则跑去北大教室自习看书
  • Quarkus框架 - 快速入门

    Quarkus框架 快速入门 64 Author xff1a zxw 64 email xff1a 502513206 64 qq com 64 Jishou University 1 前言 最近在观看云原生大会的时候 xff0c 了解到一
  • SQL异常:exist: integer = character varying

    最近在使用mybatis的时候遇到了这样的错误 SQL grammar nested exception is org postgresql util PSQLException ERROR operator does not exist
  • Seata整合nacos

    author zxw email 502513206 64 qq com 64 Jishou University 1 前言 之前一直使用的是seata 43 eureka的方式来使用 xff0c 最近自己在家的时候忽然想用nacos来试试
  • SonarQube整合maven

    64 author xff1a zxw 64 email xff1a 502513206 64 qq com 64 Jishou University sonarLint xff1a https www sonarlint org refe
  • Feign源码分析(二) - builder构建

    64 Author xff1a zxw 64 Email xff1a 502513206 64 qq com 目录 Feign源码分析 一 初探Feign 1 前言 通过上篇文章 xff0c 我们得知了Feign类中主要的元数据 xff0c
  • vector容器的三种遍历方法

    STL Standard Template Library 中vector容器是最常见的容器之一 xff0c 设计中经常需要遍历vector容器 xff0c 本文介绍三种常用的vector遍历方式 一 下标索引遍历 span class t
  • Sentinel源码分析(三) - 调用链路

    64 Author xff1a zxw 64 Email xff1a 502513206 64 qq com 目录 Sentinel源码分析 一 初识SentinelSentinel源码分析 二 Entry构建 1 前言 之前已经分析过En
  • Sentinel源码分析(四) - 限流规则

    64 Author xff1a zxw 64 Email xff1a 502513206 64 qq com 目录 Sentinel源码分析 一 初识SentinelSentinel源码分析 二 Entry构建Sentinel源码分析 三
  • Sentinel源码分析(五) - 熔断降级

    64 Author xff1a zxw 64 Email xff1a 502513206 64 qq com 目录 Sentinel源码分析 一 初识SentinelSentinel源码分析 二 Entry构建Sentinel源码分析 三
  • 无人机姿态解算:四元数及其与欧拉角的转换

    无人机姿态解算 xff1a 四元数及其与欧拉角的转换 引言 xff1a 获得无人机飞行时的飞行姿态对于无人机稳定控制来说至关重要 无人机主要通过传感器数据融合来进行状态估计 xff0c 常用于无人机的传感器包括 xff1a MPU xff0
  • 无涯教程:Docker - Node.js安装

    无涯教程网 Node js是一个JavaScript框架 xff0c 用于开发服务器端应用程序 xff0c 它是一个开放源代码框架 xff0c 可以在各种操作系统上运行 现在 xff0c 我们将看到启动和运行用于Node js的Docker
  • MVVM + dataBinding

    MVVM 43 dataBinding mvvm模式不做过多讲解 xff0c 参考下面文章或其他文章对mvvm描述 http www jianshu com p 6872b699879d 后面又发现一篇比较好的文章 xff0c 补上 htt