findViewById替代方案:Android Jetpack MVVM之BindingAdapter

2023-05-16

本文的目标是阐述BindingAdapter使用方法并以点击事件为例

在介绍它之前,我们先讲一下,布局文件中的系统属性android:onClick="" ,不知道你有没有用过,其中双引号中间就是你要触发的事件名称。不需要用findViewById获取对应控件,然后再监听click事件,若是你用过请略过,若是没有过,我们看看怎么用的。

举个例子:
在布局文件中设置android:onClick=“clickEvent”

<ImageView    
        android:layout_width="wrap_content"    
        android:layout_height="wrap_content"    
        android:onClick="clickEvent"   
        android:src="@drawable/tes" />

在activity中新建一个clickEvent函数:

public void clickEvent(View v) {   
    Toast.makeText(this, "test", Toast.LENGTH_LONG).show();
}

这样就直接可以监听ImageView的单击事件,这样是不是很方便,为啥要介绍这个呢,是因为本文BindingAdapter也要采用同样的方式来实现,只是我们不采用系统的定义的属性,而是自己定义属性。

首先要讲一下attrs.xml,它是res/values目录下的一个文件,为什么讲它?因为它跟bindingadapter紧密相连。

  • 自定义属性
    自定义性有两个部分组成,第一,属性名,也就是名字,第二,属性值,也就是属性格式format。看下面的一段代码:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="backColor" format="color">
        <enum name="redColor" value="1" />
    <declare-styleable name="MyView">
        <attr name="backColor"/>
    </declare-styleable>
</resources>

以attr开头的代表着具体某个属性。

以declare-styleable代表的某个组。例如我想为一个view自定义一个属性,假设这个view为MyView,则MyView下面定义所有属性都属于MyView组,凡是继承它的都可以使用。当然也可以为系统控件加上自定义属性。

系统属性和自定义属性是有区别的,属性名前面有“android:”都是系统属性。自定属性名没有没有什么好说的,尽量不要和系统定义的属性名雷同。

若是和系统定义的属性一样,不设置format的话,就沿用系统的。若是设置的话,就是对系统属性的重定义,但是有些系统属性格式是无法修改的。

简单介绍一下属性的format:

reference 引用
color 颜色
boolean 布尔
integer 整型
dimension
float 浮点型
string 字符型
fraction 百分比
enum 枚举型
flag

自定义属性搞定了,其实没什么难度,那么接下来,我们要看看如何自定义属性和BindingAdapter建立连接的呢。其实也很简单,还是以一个例子来说明

  • 首先,自定义属性,我们给系统的控制View自定义onClickCommand属性,只要属于View这个组的都可以使用这个属性。
<resources>
       <declare-styleable name="View">
           <attr name="onClickCommand" format="reference" />    
       </declare-styleable>
 </resources>

这个属性name,就是BindingAdapter的关键。

  • 其次,BindingAdapter

它的一般格式为:

@BindingAdapter(value={“属性名1”,“属性名2”})
public static void 函数名(参数){
//函数内容
}

具体的实例如下:新建一个文件为ViewAdapter.java,并类中添加如下代码

@BindingAdapter(value = {"onClickCommand"}, requireAll = false)
public static void click(View view, final ClickCallBack bindingCommand) {    
    view.setOnClickListener(new View.OnClickListener() {        
        @Override        
        public void onClick(View view) {           
        if (bindingCommand != null) {                
           bindingCommand.clickEvent();               
           Toast.makeText(view.getContext(), "it works", Toast.LENGTH_LONG).show();           
        } else {                
            Toast.makeText(view.getContext(), "binding command is null", Toast.LENGTH_LONG).show();           
        }        
    }    
 });
}

BindingAdapter中value要和attrs.xml中自定义属性保持一致,否则绑定不成功。

绑定的函数一定要是static的,函数名没有具体的要求,函数里面的第一个参数为要绑定对象,我们绑定的为View,那就是View;

后面的参数就是各个属性,在布局文件中一定要按顺序进行,否则可能会报错。

还需要在布局文件中应用这个属性

<ImageView
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:src="@drawable/tes"   
        binding:onClickCommand="@{viewmodel.mBindingCommand}" 
/>

到目前为止,代码层面是没有问题,但是还不能用,因为还要binding。

ActivityMainBinding binding = DataBindingUtil.setContentView(this, getLayoutResId()); 

其中ActivityMainBinding是系统自动生成的,这一步实现布局文件和属性之间进行绑定,也就是可以实现单击事件了。

最后,我们不仅要是实现事件绑定还能在ViewModel中回调,因为需要对事件进行业务的处理

在ViewModel中,需要具体实现BindingAdapter的回到,如下:

public ClickCallBack mBindingCommand = new ClickCallBack() {    
    @Override    
    public void clickEvent() {        
    Log.e("tag", "click");    
    }
};

只需要在布局文件中绑定这个回调即可生效。

但是你发现回调对象为空,因为还需要设置

binding.setVariable(BR.viewmodel, mViewModel);

这样才是完整的BindingAdapter过程。

值得注意的是binding.setVariable(BR.viewmodel, mViewModel);必须在创建ViewModel之后,否则你绑定回调参数为空,因为ViewModel没有创建为空,可以看自动生成的代码,自动生成的代码也可调试。

若是你想统一对ImageView都用Glide进行加载图片,你就可以通过这个中方式实现

@BindingAdapter({"imageUrl"})
    public static void loadImage(ImageView view, String u) {
        RequestOptions options = new RequestOptions()
                .centerCrop()
                .placeholder(R.mipmap.ic_launcher_round)
                .error(R.mipmap.ic_launcher)
                .priority(Priority.HIGH)
                .diskCacheStrategy(DiskCacheStrategy.NONE);
        Glide.with(view.getContext()).applyDefaultRequestOptions(options).load(u).transition(new DrawableTransitionOptions().crossFade(1000)).into(view);
    }

代码量会很少,效率会很高。

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

findViewById替代方案:Android Jetpack MVVM之BindingAdapter 的相关文章

  • 如何对这个字符串进行子串化

    我想得到这个字符串的 4 个部分 String string 10 trillion 896 billion 45 million 56873 我需要的4个部分是 10万亿 8960亿 4500万 和 56873 我所做的是删除所有空格 然
  • 如何重试已消耗的 Observable?

    我正在尝试重新执行失败的已定义可观察对象 一起使用 Retrofit2 和 RxJava2 我想在单击按钮时重试特定请求及其订阅和行为 那可能吗 service excecuteLoginService url tokenModel Ret
  • Android - 从资产中解析巨大(超大)JSON 文件的最佳方法

    我正在尝试从资产文件夹中解析一些巨大的 JSON 文件 我如何加载并添加到 RecyclerView 我想知道解析这种大文件 大约 6MB 的最佳方法是什么 以及您是否知道可以帮助我处理此文件的良好 API 我建议您使用GSON lib h
  • SearchView过滤ListView

    我已经实现了搜索视图来过滤我的列表视图项目 当我输入任何文本时 它会过滤列表 但当我退出搜索视图时 它不会返回原始列表项 public class PlacesListAdapter extends ArrayAdapter
  • android xamarin 中的 reCaptcha

    我想在 Xamarin android 应用程序中实现验证码 我抓住了这个在 Android 中集成 googles reCaptcha 验证 https www c sharpcorner com article how to integ
  • Android Activity 生命周期函数基础知识

    我正在测试这段代码 它显示活动所处的状态 public class Activity101Activity extends Activity String tag Lifecycle Called when the activity is
  • Adobe 是否为其 PDF 阅读器提供 Android SDK 或 API? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我希望能够在我们的应用程序内的视图中显示本地 PDF 文件 在 Android 4 03 下的平板电脑上运行 目前 我们将 Adob eR
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 是否必须删除 Intent extra?

    这可能是一个愚蠢的问题 但是是否有一条规则规定消费活动必须显式删除 Intent 额外内容 或者只有在回收 Intent 对象时才如此 换句话说 如果我总是通过执行以下操作来链接到下一个活动 Intent i new Intent MyCu
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • 你的CPU不支持NX

    我刚刚下载了 android studio 但是我遇到了一个问题 当我运行它时 它说你的 cpu 不支持 NX 我应该怎么办 NX 或实际上是 NX 处理器位 是处理器的一项功能 有助于保护您的 PC 免受恶意软件的攻击 当此功能未启用并且
  • Ubuntu 16.04 - Genymotion:找不到 /dev/hw_random

    I install Genymotion on the Ubuntu 16 04 64Bit I created a virtual emulator for Android 6 0 then I run this emulator but
  • 如何发布Android .aar源以使Android Studio自动找到它们?

    我正在将库发布到内部 Sonatype Nexus 存储库 Android Studio 有一个功能 可以自动查找通过 gradle 引用的库的正确源 我将 aar 的源代码作为单独的 jar 发布到 Nexus 但 Android Stu
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 尝试在 ubuntu 中编译 android 内核时出错

    我正在尝试从源代码编译 Android 内核 并且我已经下载了所有正确的软件包来执行此操作 但由于某种原因我收到此错误 arm linux androideabi gcc error unrecognized command line op
  • 在 android DatePickerDialog 中将语言设置为法语

    有什么办法可以让日期显示在DatePickerDialog用法语 我已经搜索过这个但没有找到结果 这是我的代码 Calendar c Calendar getInstance picker new DatePickerDialog Paym
  • Android访问远程SQL数据库

    我可以直接从 Android 程序访问远程 SQL 数据库 在网络服务器上 吗 即简单地打开包含所有必需参数的连接 然后执行 SQL 查询 这是一个私人程序 不对公众开放 仅在指定的手机上可用 因此我不担心第三方获得数据库访问权限 如果是这
  • 在activity_main.xml中注释

    我是安卓新手 据我所知 XML 中的注释与 HTML 中的注释相同 使用 形式 我想在 Android 项目的 Activity main xml 配置文件中写一些注释 但它给了我错误 值得注意的是 我使用的是 Eclipse 但目前 我直
  • Android:膨胀布局时出现 StackOverFlowError 和 InvokingTargetException

    首先 对不起我的英语 我在膨胀布局时有一个问题 我有一个自定义视图 从 LinearLayout 扩展而来 称为按钮帮助 我在名为的布局上使用该视图加载活动 我的以下代码在所有设备和模拟器上都能完美运行 但具有 QVGA 屏幕 例如 Sam
  • 将 Intent 包装在 LabeledIntent 中以用于显示目的

    要求 我的应用程序中有一个 共享 按钮 我需要通过 Facebook 分享 我需要选择是否安装原生 Facebook 应用程序 我们的决定是 如果未安装该应用程序 则将用户发送到 facebook com 进行分享 当前状态 我可以检测何时

随机推荐

  • JS五子棋(AI)

    JS五子棋 AI xff09 跟随算法 xff1a 白棋始终跟随当前黑棋周围 span class token doctype span class token punctuation lt span span class token do
  • Discuz7.2漏洞

    发布日期 xff1a 2010 01 06 更新日期 xff1a 2010 01 07 受影响系统 xff1a Discuz Discuz 7 1 Discuz Discuz 7 2 描述 xff1a Discuz 是一款华人地区非常流行的
  • vfp常见问题和代码

    1 VFP为何在编译时提示找不到菜单生成程序 xff1a 设置 GENMENU 系统内存变量到适当的路径和文件 例如 假定 FoxPro 安装在 C 盘上的 VFP 中 在命令窗口打入以下命令来恢复系统变量的值 GENMENU 61 34
  • VFP中Form的重要概念

    本文所指的 34 表单窗口属性 34 是指那些不但影响表单本身的特征 xff0c 而且对表单之外 项目之中的其它 34 元件 34 有影响的表单属性 xff0c 它们是 xff1a 属性 意义 可选值 黑体为默认值 DeskTop 指定表单
  • MacOS M1芯片安装PyQt5的方法

    MacOS M1芯片安装 PyQt5 的方法 关于PyQt5 PyQt5 是GUI 小部件工具包 xff0c 是 Qt 的 Python 接口 xff0c 是图形界面开发库 xff0c 用于程序的用户交互界面 按照官网 PyQt5 pypi
  • iOS富文本编辑(在label里显示文字和图片)

    在开始写之前先看一下效果图 在此效果图中有富文本中指定的位置添加图片 xff0c 还有最后位置添加的图片信息 代码如下 调用方法 给label赋值 NSString Str 61 64 34 中国人民解放军万岁 xff0c 中华人民共和国万
  • ubuntu下安装VNC远程桌面的详细步骤

    作者 xff1a 转自 xff1a http www 5loveb com 4 515 html Virtual Network Computing VNC 是进行远程桌面控制的一个软件 客户端的键盘输入和鼠标操作通过网络传输到远程服务器
  • 服务器esxi安装

    一 部署raid0或raid1 xff08 Raid0的配置过程与Raid1大致相同 xff0c 唯一不同是在选择Raid级别这一步选择Raid0即可 xff09 xff08 一 xff09 在RAID卡适配器自检页面按组合键Ctrl 43
  • MFC编辑框数据读写

    简介 xff1a 有几种常用的获取编辑框内容和写入的方法 xff0c 初学者往往容易迷惑 1 第一种 通过GetDlgItem和GetWindosText char szEdit 10 61 0 int nEdit 61 0 GetDlgI
  • Peer cert cannot be verified or peer cert invalid 解决方法

    yum安装软件时报Peer cert cannot be verified or peer cert invalid xff0c 如下图所示 xff1a 解决办法 xff1a 在 etc yum conf文件后追加sslverify 61
  • 在anaconda中为jupyter安装扩展插件

    安装过程 xff1a 1 在开始菜单中打开Anaconda Prompt 2 执行如下安装命令 xff1a conda install c conda forge jupyter contrib nbextensions conda ins
  • 降低代码耦合度的方法 -依赖注入

    降低代码耦合度的方法 依赖注入 什么是依赖注入为什么要使用依赖注入Laravel中的依赖注入 什么是依赖注入 什么是依赖注入 xff0c 就要先了解什么是依赖 在面向对象语言中 xff0c A类需要引用B类中Y方法的 xff0c 则称A类和
  • 接入腾讯应用宝(YSDK)注意事项

    接入腾讯ysdk只想说 xff0c 其文档写的真是差 xff01 很多东西摸不着头尾 xff0c 在这期间走了很多坑 第一个 xff1a 拉起手Q时 xff0c 出现100044画面错误 造成这个的因素有很多 xff1a 1 xff0c 未
  • ubuntu20.04 使用root用户自动登录系统

    Ubuntu20 04安装完成之后 xff0c 默认是没有root账户登录权限的 xff0c 这样在操作系统时有诸多不便 xff0c 比如新建一个文件都提示权限不够 xff01 不过可以通过创建的普通用户获取管理员权限 xff0c 然后修改
  • Ubuntu——虚拟显示器的配置、卸载、修改分辨率

    参考博客 xff1a 安装虚拟显示器 xff1a VNC远程登录无外接显示器的Ubuntu Desktop卸载虚拟显示器 远程服务器虚拟显示器 xff08 Ubuntu 20 04 LTS xff09 修改分辨率 xff1a Ubuntu
  • 修改ubuntu的默认路由

    1 sudo route del default gw 192 168 6 1 删除默认路由 2 sudo route add default gw 192 168 6 1 添加默认路由 route 命令参考https www cnblog
  • 安装opencv3.2时出现 ICV: Failed to download ICV package: ippicv_linux_20151201.tgz.

    到链接 https pan baidu com s 1tUn4so6BZc8MdVz0FbtWLA 提取码 sktn xff0c 下载ippicv linux 20151201 tgz 并替换 opencv 3 2 0 3rdparty i
  • nuscenes数据读取和解析

    1 nuScenes数据集标注格式的说明 https blog csdn net qq 29679623 article details 103698313 utm medium 61 distribute pc relevant none
  • ubuntu16.04使用systemback给工控机还原系统

    1 由于使用 systemback备份系统的移动硬盘装有nvidia 460的驱动 xff0c 导致从移动硬盘启动后进入systemback备份的Ubuntu系统会出现循环登录的情况 xff0c 因此需要先卸载 systemback备份的U
  • findViewById替代方案:Android Jetpack MVVM之BindingAdapter

    本文的目标是阐述BindingAdapter使用方法并以点击事件为例 在介绍它之前 xff0c 我们先讲一下 xff0c 布局文件中的系统属性android onClick 61 34 34 xff0c 不知道你有没有用过 xff0c 其中