自定义属性

2023-10-26

TypeArray 用来简化资源类型判断,declare-styleable 用来生成资源 ID 数组和对应的索引值

自定义属性的声明文件(values/attrs.xml)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="test">
        <attr name="text" format="string" />
        <attr name="testAttr" format="integer" />
    </declare-styleable>
</resources>

自定义 View

public class MyTextView extends View {

  public MyTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test);
    String text = ta.getString(R.styleable.test_testAttr);
    int textAttr = ta.getInteger(R.styleable.test_text, -1);
    ta.recycle();
  }
}

Xml 布局文件

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:zhy="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.test.MyTextView
        android:layout_width="100dp"
        android:layout_height="200dp"
        zhy:testAttr="520"
        zhy:text="@string/hello_world" />

</RelativeLayout>

代码看不懂不要紧,后面慢慢分析,我们先说一下 View 构造方法中的 AttributeSet 参数,首先AttributeSet 保存的是 View 在布局文件中声明的所有属性,而且我们的确可以通过它去获取属性键值对,下面我们修改一下 MyTextView 中的代码:

public class MyTextView extends View {
  public MyTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    int count = attrs.getAttributeCount();
    for (int i = 0; i < count; i++) {
      String attrName = attrs.getAttributeName(i);
      String attrVal = attrs.getAttributeValue(i);
      Log.e(TAG, "attrName = " + attrName + " , attrVal = " + attrVal);
    }
  }
}

运行结果为:

MyTextView(4692): attrName = layout_width , attrVal = @2131165234
MyTextView(4692): attrName = layout_height , attrVal = @2131165235
MyTextView(4692): attrName = testAttr , attrVal = 520
MyTextView(4692): attrName = text , attrVal = @2131361809

通过结果我们发现,打印出来的 text 属性是以 @ 开头的,我们改一下代码

public class CustomView extends View {
  public CustomView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    if (attrs == null) return;
    int count = attrs.getAttributeCount();
    for (int i = 0; i < count; i++) {
//      if(attrs.getAttributeName(i).equals("text")) {
      if (attrs.getAttributeNameResource(i) == R.attr.text) {
        int resValue = attrs.getAttributeResourceValue(i, -1);
        if (-1 != resValue) {
          Log.e("offer", getResources().getString(resValue));
        } else {
          Log.e("offer", attrs.getAttributeValue(i));
        }
      }
    }
  }
}

在上面的例子中,我们首先通过 getAttributeResourceValue 判断资源是否是引用类型,然后再去解析对应的资源,这样就可以打印出来了,所以说 TypedArray 可以用来简化获取资源的流程

另外,我们说一下 declare-styleable 标签,该标签也是简化我们代码的,在自定义属性时,我们也可以省略该标签,我们改一下最上面的自定义属性声明文件:

自定义属性的声明文件(values/attrs.xml)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="text" format="string" />
    <attr name="testAttr" format="integer" />
</resources>

自定义 View

public class MyTextView extends View {

  private static final int[] mAttr = { android.R.attr.text, R.attr.testAttr };
  private static final int ATTR_TEXT = 0;
  private static final int ATTR_TESTATTR = 1;

  public MyTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray ta = context.obtainStyledAttributes(attrs, mAttr);
    String text = ta.getString(ATTR_TEXT, -1);
    int textAttr = ta.getInteger(ATTR_TESTATTR);
    ta.recycle();
  }
}

我们发现,即使没有 declare-styleable 标签,我们也可以实现自定义属性,该标签只是自动帮助我们生成了 attr 数组和对应的下标序号

另外,我们在声明自定义属性时,也可以复用系统的属性:

<declare-styleable name="test">
    <attr name="android:text" />
    <attr name="testAttr" format="integer" />
</declare-styleable>

这里我们是使用已经定义好的属性,不需要去添加 format 属性(注意声明和使用的区别,差别就是有没有 format),然后在类中这么获取:ta.getString(R.styleable.test_android_text); 布局文件中直接 android:text="@string/hello_world" 即可。说白了,属性还是系统的属性(attr 并没有增加,只是 declared-styleable 数组中多了一个值,另外多了一个下标序号而已)

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

自定义属性 的相关文章

随机推荐

  • 学生考试信息管理系统c语言程序,C语言版学生信息管理系统

    本文实例为大家分享了C语言版学生信息管理系统的具体代码 供大家参考 具体内容如下 一 题目分析 1 功能概述 1 查询学生信息 2 添加学生信息 3 修改学生信息 4 删除学生信息 5 刷新学生信息 6 保存学生信息 7 输出当前学生信息
  • 简单的Kali Linux学习教程

    第一步 安装Kali Linux 您可以从Kali Linux官方网站下载Kali Linux的安装镜像文件 安装程序提供了多种选项 包括在磁盘上安装 在虚拟机中运行等 第二步 更新系统 安装完成后 首先需要通过以下命令更新系统 sudo
  • 【思特沃克前端校招笔试、一面、二面】

    思特沃克 1 前端海外岗 四月中旬收到笔试 写完后几天约一面 一面后两周约二面 2 大概两周后收到邮件答复一面过了约二面 结果点约面链接进去没有显示 通过该邮件咨询了下只要等待下次邀约就行 3 结果几天后收到了感谢信 邮件咨询校招组也无回应
  • 基于bp神经网络的房价预测,房价预测 神经网络

    Python 与深度学习有哪些与建筑设计相接轨的可能性 关注这个问题快一周了 到目前来说还是没发现什么太大的惊喜 我感觉建筑设计界还是要学习一个 不要看到深度学习很火 就弄个大新闻 把这玩意往建筑设计上搬呀 其实深度学习这事儿到底怎么就能和
  • LightGBM 源码学习 (2022-5)

    之前在Linux系统上调试的博文 LightGBM源码学习 准备篇 系统 MacOS 软件 Clion 感觉最新的commit可能有坑 退回到2021年年初的commit code link git checkout 967b45c6866
  • 【爬虫自动生成代码】Playwright系列文章二

    Playwright系列文章 目录 Playwright系列文章 前言 一 Playwright录制功能 二 使用步骤 1 查看命令参数 help 2 命令启动浏览器 总结 前言 Playwright是类似于selenium Pyppete
  • android support design jar,错误:程序类型已存在:android.support.design...

    我在构建项目时遇到以下错误 在这个项目中没有使用CoordinatorLayout 刚刚在build gradle中添加为依赖项 我使用的是Android Studio 3 2 Canary 4 logcat的 AGPBI kind err
  • uv纹理坐标设定与贴图规则

    1 什么是UV 对于三维模型 有两个最重要的坐标系统 一是顶点的位置 X Y Z 坐标 另一个就是UV坐标 什么是UV 简单的说 就是贴图影射到模型表面的依据 完整的说 其实应该是UVW 因为XYZ已经用过了 所以另选三个字母表示 U和V分
  • VUE 时间转换的几种方式

    时间转换 做一个项目肯定会关系到很多的数据类型 数据类型之间都是可以转化的 前端有时候从后端拿到的时间不符合标准 此时就需要转换以后再去使用 转换有两种方式 看你个人比较喜欢哪一种 这里已时间转换为例子 过滤器filter 全局过滤器 在m
  • unity 发布webGl ISS发布

    推荐 https blog csdn net weixin 43926289 article details 122943814 其他的按照步骤配置就行了 主要是 一定要按图来 OVER 另外说一下本地浏览器直接打开index 有些项目要求
  • mysql服务器多线程参数_MySQL服务器的线程数查看方法

    MySQL的variables和status是管理维护的利器 就类似Oracle的spfile和v 表 MySQL通过系统变量记录很多配置信息 比如最大连接数max connections mysql gt show variables l
  • Java从零开始追大牛系列_0

    在此先做做我介绍 鄙人二流大学通信工程专业一名大三 即将大四 学生 由于并无志向在专业学术领域有所建树 因此并未涌入考研大军 只求毕业后Java编程技术过硬 可寻的一份喜欢的工作 特此准备写词系列博客 因为软件并非自己专业 只是兴趣使然 但
  • 【Transformer】18、ACMix:On the Integration of Self-Attention and Convolution

    文章目录 一 背景和动机 二 方法 三 效果 一 背景和动机 卷积核自注意机制是两个很有效的特征提取方法 但这两个方法通常被认为是两种不同机制的方法 卷积方法是对局部进行特征抽取 全局特征共享 自注意力方法是全局像素的权重提取 本文作者认为
  • verilog手撕代码7——固定优先级仲裁器和轮询仲裁器

    文章目录 前言 一 固定优先级仲裁器 Fixed Priority Arbiter 1 case if语句实现 2 for循环语句实现参数化结构 二 轮询仲裁器 Round Robin Arbiter 1 case语句实现 2 for循环实
  • 在R语言中使用text函数可以在可视化图像中添加样本标签

    在R语言中使用text函数可以在可视化图像中添加样本标签 text函数允许我们在图形中的指定位置添加文本元素 这对于标记数据点 添加注释或创建自定义标签非常有用 在本文中 我们将学习如何使用R语言的text函数在可视化图像中添加样本标签 首
  • 电源模块的降额曲线

    大家好 这里是大话硬件 今天想写这篇文章来分享在前段时间了解的一个知识点 电源模块的降额曲线 为什么要写这个呢 对于专门做电源的同学来说 肯定觉得很简单 但是对于一个非电源行业的人来说 曲线应该如何解读 业内是如何测试出来的 不一定十分完全
  • Java-网络原理

    目录 一 网络互连 局域网LAN 广域网WAN 二 网络通信基础 IP地址 端口号 认识协议 三 五元组 四 协议分层 五 OSI七层模型 六 TCP IP五层 或四层 模型 网络分层对应 七 封装和分用 一 网络互连 随着时代的发展 越来
  • (超详细!)【C语言】单链表的增删查改(附图解,源码)

    单链表学习导航 一 前言 二 准备工作 1 对单链表运行原理的简单理解 2 区域化编辑 三 SList h头文件引用区 1 单链表节点的创建 2 单链表功能函数的声明 四 SListTest c测试区 五 SList c功能实现区 1 动态
  • Python类型强制转换和字符串的操作

    Python类型强制转换和字符串的操作 类型强制转换 字符串的操作 name I Love The World The Dog print name 0 下标取值 print len name 字符串长度 print name 2 倒数第二
  • 自定义属性

    TypeArray 用来简化资源类型判断 declare styleable 用来生成资源 ID 数组和对应的索引值 自定义属性的声明文件 values attrs xml