Android自定义控件--如何在XML文件中使用自定义属性

2023-11-17

前言

你好, 我是Cici。这几天在做一个小项目的时候,用到了自定义控件,为了方便在XML中进行配置,于是需要用到自定义属性,特此记下用法,方便复习的同时也希望对大家有所帮助。

一、为什么需要自定义控件

Android本身提供了很多控件,比如TextView、ImageView等,在实际开发中,有时候单个的控件并不能很好的满足业务需求,因此我们会将多种控件组合在一起,形成一个具有特定功能的自定义控件,就好比零件的拼装,将多个小零件最后拼成一个大零件来使用。

二、具体步骤

1.首先我们创建一个 layout xml文件:

例如:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/mi_layout">

    <View
        android:id="@+id/view_1"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/line"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/image_1"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:background="@color/blue"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginStart="10dp" />

    <TextView
        android:id="@+id/text_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="@id/image_1"
        app:layout_constraintStart_toEndOf="@id/image_1"
        android:layout_marginStart="8dp"
        android:text="预约申请"
        android:textSize="14sp"
        android:textColor="@color/black" />

    <TextView
        android:id="@+id/text_2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="@id/text_1"
        app:layout_constraintTop_toBottomOf="@id/text_1"
        app:layout_constraintBottom_toBottomOf="@id/image_1"
        app:layout_constraintEnd_toStartOf="@id/image_2"
        android:layout_marginEnd="66dp"
        android:layout_marginTop="10dp"
        android:ellipsize="end"
        android:lines="1"
        android:text="李老师申请实验室"
        android:textSize="12sp"
        android:textColor="@color/gray" />

    <androidx.constraintlayout.utils.widget.ImageFilterView
        android:id="@+id/image_2"
        android:layout_width="8dp"
        android:layout_height="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginEnd="15dp"
        android:layout_marginTop="20dp"
        app:roundPercent="1"
        android:background="@color/color_f31515" />

    <View
        android:id="@+id/view_2"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/line"
        app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
复制代码

具体效果如下图所示:

2.为自定义控件创建java类:


public class MessageItem extends ConstraintLayout {

    private LayoutMessageItemBinding binding;

    ConstraintLayout layout;
    ImageView iv1;
    TextView tv1;
    TextView tv2;
    ImageView iv2;

    private int imageResource1 = R.color.bottom_down;
    private int imageResource2 = R.color.color_f31515;
    private String text1 = "";
    private String text2 = "";
    private boolean showSpot = true;


    public MessageItem(@NonNull Context context) {
        this(context, null);
    }

    public MessageItem(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MessageItem(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MessageItem);
        imageResource1 = array.getResourceId(R.styleable.MessageItem_imageResource1, imageResource1);
        imageResource2 = array.getResourceId(R.styleable.MessageItem_imageResource2, imageResource2);
        text1 = array.getString(R.styleable.MessageItem_text1);
        text2 = array.getString(R.styleable.MessageItem_text2);
        showSpot = array.getBoolean(R.styleable.MessageItem_showSpot, true);
        array.recycle();
        if (isInEditMode()) {
            return;
        }
        binding = LayoutMessageItemBinding.inflate(LayoutInflater.from(MyApplication.getContext()), this, true);
        bindView();
        init();
    }

    private void bindView() {
        layout = binding.miLayout;
        iv1 = binding.image1;
        iv2 = binding.image2;
        tv1 = binding.text1;
        tv2 = binding.text2;
    }

    private void init() {
        setImageResource1(imageResource1);
        setImageResource2(imageResource2);
        setText1(text1);
        setText2(text2);
        setShowSpot(showSpot);
    }

    private MessageItem setImageResource1(int resId) {
        this.iv1.setBackgroundResource(resId);
        return this;
    }

    private MessageItem setImageResource2(int resId) {
        this.iv2.setBackgroundResource(resId);
        return this;
    }

    private MessageItem setText1(String text) {
        this.tv1.setText(text);
        return this;
    }

    private MessageItem setText2(String text) {
        this.tv2.setText(text);
        return this;
    }

    private MessageItem setShowSpot(boolean b) {
        this.iv1.setVisibility(b ? VISIBLE : GONE);
        return this;
    }
}
复制代码

3.在res/values下,新建一个attrs.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MessageItem">
        <attr name="imageResource1" format="reference" />
        <attr name="imageResource2" format="reference" />
        <attr name="text1" format="string" />
        <attr name="text2" format="string" />
        <attr name="showSpot" format="boolean" />
    </declare-styleable>
</resources>
复制代码

4.最后使用:

在使用的时候,我们只需要在相应的 XML 文件中引入即可,例如:

<com.example.lims.widget.MessageItem
    android:id="@+id/f_message_i3"
    app:text1="维修意见"
    app:text2="张同学向您提出设备维护意见"
    app:imageResource1="@drawable/message_3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/f_message_i2"
    app:layout_constraintStart_toStartOf="parent" />
复制代码
<com.example.lims.widget.MessageItem
    android:id="@+id/f_message_i1"
    app:text1="预约申请"
    app:text2="王老师向您申请实验室"
    app:imageResource1="@drawable/message_1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_constraintTop_toBottomOf="@id/toolbar"
    app:layout_constraintStart_toStartOf="parent" />
复制代码

其中,app:text1、app:text2、app:imageResource1 为自定义属性。这样就可以根据业务需要,为我们的自定义控件设置不同的属性值,最终得到不同的效果。

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

Android自定义控件--如何在XML文件中使用自定义属性 的相关文章

  • Android 是否可以使用并发插值器?

    我有一组两个动画 两个动画使用过冲插值器一起运行
  • 插入耳机时有什么方法可以强制音频通过扬声器吗?

    我已经尝试过推荐的 setSpeakerphoneOn true 以及不推荐的 AudioSystem setForceUse AudioSystem FOR MEDIA AudioSystem FORCE SPEAKER 但两者都不起作用
  • RecyclerView 上的删除按钮删除了错误的项目

    我正在使用 Firestore 适配器RecyclerView我在使用 删除 按钮时遇到问题 当我按下它时 它会删除错误的项目 而不是我想要的项目 这是我的按钮内部的代码onBindViewHolder protected void onB
  • Flutter - 使用 Android 下载指示器下载文件

    我正在尝试下载邮件系统的附件 为此 我正在使用颤振下载器 https pub dartlang org packages flutter downloader但我需要通过我的 http 客户端传递我的令牌 我认为这个插件没有处理这个问题 我
  • 是否可以仅使用一个实例来创建片段

    我只是想知道 片段创建只能有一个实例或单例吗 我经历了谷歌iosched项目也 他们只是简单地创造 Fragment a new Fragment 每当他们想要 假设例如 public static FragmentManager inst
  • 使用自定义 cordova 插件未找到类异常

    我正在开发一个打印应用程序 它使用自定义 API 通过 USB 访问打印机 因此我需要一个自定义 Cordova 插件 我开始开发它 这是一个非常好的挑战 但目前也非常令人沮丧 因为我不明白为什么我的插件不能正确使用 事情是 1 插件安装正
  • Android 版 Qt 和 BoringSSL

    我正在开发一个基于 Qt 的 Android 应用程序 它使用 QSslSocket 下载数据 由于 Android 从 OpenSSL 转向 BoringSSL 因为依赖 OpenSSL 库的 Marshmallow Qt 程序在 And
  • Android - 检测电容式触摸屏上的触摸压力?

    我听说过 MotionEvent e float press e getPressure 但这只会在没有触摸时返回 0 当我的手指触摸屏幕时返回 1 是否可以找到手指在触摸电容屏上施加的压力值 或者我的预感是否正确 即这只适用于电阻屏幕 M
  • Android 上下文不在活动中?还有其他无活动编程吗?

    我会非常努力地将其变成一个综合问题 我正在编写一个方法来获取一个包含 Android 设备城市名称的字符串 该名称由LocationManager and getLastKnownLocation 等等 然后我意识到我需要在另一个活动中再次
  • DrawBitmapMesh 如何在 Android Canvas 中工作

    我想在矩形上绘制位图 我使用以下值 this meshWidth 1 this meshHeight 1 this verts new float 8 this points 0 x float this getWidth 4 this p
  • 如何使用 Eclipse 从我的设备检索我的应用程序的沙箱?

    我有一个 Android 应用程序 它使用共享首选项 我使用 Eclipse 在 Android 设备中运行该应用程序 我想拉整个sandbox来自设备到桌面这样我就可以手动查看sharedPreferences的内容 我点击了DDMS并点
  • 小部件双击

    我有一个小部件 AppWidgetProvider 我想知道是否有办法支持多次点击 示例 1 如果是第一次点击widget 那么widget的ImageButton会发生变化 例如 改变颜色 2 如果是第二次 则打开一个Activity A
  • Android:RecyclerView 项目上下文菜单问题

    我正在尝试实现一个 RecyclerView 单击每个项目时 都会弹出一个上下文菜单 我已引用此的答案 评论question https stackoverflow com questions 26466877 how to create
  • Android 浏览器缩放?

    我正在尝试为 Android 创建一个移动网站 当我将主体宽度设置为 480px 屏幕宽度 时 结果比我预期的大 50 左右 看来 android 正在缩放它所绘制的内容并弄乱了我所有的布局 有谁知道如何禁用它或解决它 我已经在使用这个 您
  • 如何让更宽的图像在后台滚动

    就像 LinkedIn 中的前三个屏幕一样 Splash 登录 注册按钮 登录 注册表单 它们都具有相同的背景图像 但是当我们从一个活动移动到另一个活动时 背景图像从右滚动到左侧 我只能尝试overridePendingTransition
  • 将 wgs 84 转换为纬度/经度

    你好 我在弄清楚如何在坐标类型之间进行转换时遇到了一些麻烦 我有一个坐标集列表 其描述如下 坐标始终采用 WGS84 系统 所有坐标 a 均表示为整数 值 x 和 y 其中坐标值乘以 1 000 000 一个例子 559262 631951
  • Android 调整图片大小

    我的图像存储在 SD 卡上 每个大小约为 4MB 我想调整每个的大小 而不是将其设置为 ImageView 但我不能使用BitmapFactory decodeFile path 因为异常 java lang OutOfMemoryErro
  • 使用“是/否”对话框拦截链接 LinkMovementMethod

    我有一个标准LinkMovementMethod https developer android com reference android text method LinkMovementMethod建立在我的TextView当用户触摸链
  • 在 Android 版 ORMLite 中加入类会引发 SQL 异常:找不到外部类,反之亦然

    我正在尝试使用 QueryBuilder 为两个不同的类创建一个联接查询 一个Product类和一个Coupon类 引用 Product 属性 storeId public class Coupon DatabaseField column
  • Android 中的定制数字时钟

    您好 我想以 HH mm AM PM 的格式在我的应用程序中显示时间 数字时钟还包括秒 即 HH mm ss 上午 下午 如何避免显示秒 有没有什么可行的办法 请帮助我 您必须克隆该文件DigitalClock java要在您的应用程序中使

随机推荐

  • CTK系列之插件制作

    CTK插件制作 说明 1 将上篇我们提到的ctk路径创建ctk pro包含到每一个插件中 include PWD ctk ctk pri 2 可以自定义一个公共代码仓common并创建common pri同样包含到每一个插件中 includ
  • php前端取blob数据,前端读取Blob内容

    简述 前端由于安全方面的因素 不能直接对文件进行写操作 但是在实际的业务需求中 难免会遇到各种各样文件的下载 预览 如果服务端下载文件是以流的形式传递到前端 前端通常是将流转换为objectURL 借用a标签的download属性 进行文件
  • 后台扫描工具 - 御剑(珍藏版)附下载

    版本说明 御剑后台扫描珍藏版 下载地址 安装包放下方网盘里了 链接 https pan baidu com s 1Bn7GtWb7AStcjzVahFOjSQ 提取码 zkaq 使用环境 windows 标题工具说明 御剑后台扫描珍藏版是T
  • Pytorch版本的Ernie Health源码详解

    Pytorch版本的Ernie Health源码详解 一 目录架构 二 尝试使用Ernie Health import torch 查看torch版本 torch version 1 12 0 cpu 查看设备是否有GPU资源 device
  • 方差分析、T检验、卡方分析如何区分

    方差分析 T检验 卡方分析如何区分 差异研究的目的在于比较两组数据或多组数据之间的差异 通常包括以下几类分析方法 分别是方差分析 T检验和卡方检验 1 三个方法的区别 1 其核心的区别在于 数据的类型不一样 如果是定类和定类 此时应该使用卡
  • 在MacOS上安装GraphViz并用PlantUML绘制UML图

    文章目录 在MacOS上安装GraphViz并用PlantUML绘制UML图 在MacOS上安装Graphviz 在VSCode上安装PlantUML插件 用PlantUML绘制UML图 在MacOS上安装GraphViz并用PlantUM
  • Python矩阵赋值详解

    在Python中 矩阵是一种常见的数据结构 广泛应用于数学 科学和工程领域 在本文中 我们将详细介绍如何使用Python给矩阵赋值 在Python中 可以使用多种方式来表示和操作矩阵 其中最常用的是使用嵌套列表或NumPy库中的数组对象 我
  • JavaScript高级技巧:深入探索JavaScript语言的高级特性和用法

    当我们谈论JavaScript高级技巧时 以下是一些示例来说明这些概念 闭包 Closures function outerFunction var outerVariable Hello function innerFunction co
  • 自从学了这套框架,自动化+性能都搞定了

    框架介绍 1 HttpRunner 是一款面向 HTTP S 协议的通用测试框架 只需编写维护一份YAML JSON脚本 即可实现自动化测试 性能测试 线上监控 持续集成等多种测试需求 2 Locust Locust是一款易于使用的分布式用
  • 数据库关系代数运算之连接

    联接有三种 联接和自然联接 这里是算术比较符 外联接 1 联接 从R和S的笛卡儿乘积中选取满足条件 i j 的元组 2 自然联接 naturaljoin 两个关系R和S的自然联接操作具体计算过程如下 计算R S 设R和S的公共属性是A1 A
  • 【转】SQL删除的三个语句:DROP、TRUNCATE、 DELETE 的区别

    主要介绍了SQL删除语句DROP TRUNCATE DELETE 的区别 帮助大家更好的理解和学习sql语句 感兴趣的朋友可以了解下 DROP 1 DROP TABLE test 删除表test 并释放空间 将test删除的一干二净 TRU
  • CMake Error: Maybe need administrative privileges.

    安装opencv时 到make install 这一步报错 解决 权限不够 前面加上sudo 即 sudo make install
  • qt中的QString::number()的精度使用问题

    1 QString number average f 5 这里的 f 表示的是 f 方式结果是0 00 所以后面的5表示的就是输出的时候保留5位小数 通常 QString str str QString number 23 34567899
  • 使用tp5内cache缓存,存储手机短信验证码

    设置手机短信验证码缓存方法 设置手机短信验证码缓存 User JW Email jw 333 163 com Date param data cache public function setRegSmsCache data cache C
  • Gitee API的使用|如何批量删除Gitee下的所有仓库

    前言 那么这里博主先安利一些干货满满的专栏了 首先是博主的高质量博客的汇总 这个专栏里面的博客 都是博主最最用心写的一部分 干货满满 希望对大家有帮助 高质量博客汇总https blog csdn net yu cblog category
  • python语音播报

    python3 pip install pyttsx3 python2 pip install pyttsx 文本转语音 import pyttsx3 import time str Come on Catherine engine pyt
  • java 强密码验证策略工具类

    java 强密码验证策略工具类 package com neusoft caeid common utils import java util regex Matcher import java util regex Pattern aut
  • ChatGPT论文考试满绩,高等教育该如何应对人工智能挑战?

    近日 ChatGPT引发热议 一方面 ChatGPT表现亮眼 有大学生利用ChatGPT在开卷课堂上取得满绩的优异成绩 另一方面 部分院校 学术期刊却对ChatGPT在高等教育领域的推进保持谨慎态度 甚至有高校明确禁止这项工具技术的使用 那
  • 算法题:Rod Cutting

    算法题 Rod Cutting 一 题目 二 代码 三 结果 一 题目 二 代码 lengths 1 1 3 4 lengths 5 4 4 2 2 8 def rodOffcut lengths resut resut append le
  • Android自定义控件--如何在XML文件中使用自定义属性

    前言 你好 我是Cici 这几天在做一个小项目的时候 用到了自定义控件 为了方便在XML中进行配置 于是需要用到自定义属性 特此记下用法 方便复习的同时也希望对大家有所帮助 一 为什么需要自定义控件 Android本身提供了很多控件 比如T