android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」

android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」最近在模仿今日头条,发现它的很多属性都是通过自定义控件并设定相关的配置属性进行配置,于是便查询了解了下declare-styleable,下面我把自己的使用感受和如何使用进行说明下。declare-styleable:declare-styleable是给自定义控件添加自定义属性用的。官方的相关内部控件的配置属性文档:http://developer.android.com/refer

大家好,又见面了,我是你们的朋友全栈君。

最近在模仿今日头条,发现它的很多属性都是通过自定义控件并设定相关的配置属性进行配置,于是便查询了解了下declare-styleable,下面我把自己的使用感受和如何使用进行说明下。

declare-styleable:declare-styleable是给自定义控件添加自定义属性用的。

官方的相关内部控件的配置属性文档:http://developer.android.com/reference/android/R.styleable.html

如果不知道如何查看源码:点击这里


起初,在自定义控件的时候,会要求构造3个方法中的一个或多个,好比我自定义的控件PersonView,

public PersonView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public PersonView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public PersonView(Context context, AttributeSet attrs) {
		super(context, attrs);
}

其中的AttributeSet attrs一般都没给它配置和使用,所以不知道这个东西到底怎么用,后来查看源码发现,这个配置在默认情况下使用的是系统自己的默认配置,一旦你直接设定了它的属性,默认属性就会被你的赋值所替代。

下面我们拿TextView的源码看看AttributeSet是如何进行操作的。

初始化时候,在布局文件中写android:text=”拉拉”;

android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」


初始化TextView的时候,它的类中的属性都会初始化;


android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」


接着往下看,你可以看到以下代码:


        TypedArray a = theme.obtainStyledAttributes(
                    attrs, com.android.internal.R.styleable.TextViewAppearance, defStyle, 0);
        TypedArray appearance = null;
        int ap = a.getResourceId(
                com.android.internal.R.styleable.TextViewAppearance_textAppearance, -1);
        a.recycle();
        if (ap != -1) {
            appearance = theme.obtainStyledAttributes(
                    ap, com.android.internal.R.styleable.TextAppearance);

这个就是系统在默认的资源文件R.styleable中去获取相关的配置。

如果appearance不为空,它就会去寻找获取相关属性,接着往下看。

android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」

此时的text = “”;     就是准备输出的字符串初始化。

之后它便会查找你布局文件XML中是否设定给了它text属性值

android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」

之前我们设定过android:text=”拉拉;  所以它便会得到相关的赋值,之后调用

<span style="font-size:18px;"> setText(text, bufferType);
 if (hint != null) setHint(hint);
</span>

输出该字符串。当资源检查赋值完毕后,调用a.recycle();释放。
同理也可以发现,像hint,textcolor这类属性都是这么初始化赋值的。


思路:

自定义控件并且自定义属性的情况下,你可以通过这样去获取判断是否配置了相关的属性,并进行赋值操作。


从源码那边我们大体知道了一个控件的属性配置和初始化流程,下面就让我们按照这个思路去自己学习下如何自定义配置。


下面我要写一个继承了TextView的PersonView类,给它设定属性配置,之后实现属性的显示。

1.首先,先写attrs.xml

在res-vlaues文件夹下创建资源文件attrs.xml或则自定义一个资源文件xx.xml,都可以。

之后在里面配置declare-styleable ,name为PersonAttr

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="PersonAttr">
        <attr name="name" format="reference" />
        <attr name="sex" format="reference" />
        <attr name="age" format="integer" />
        <attr name="weight">
            <flag name="fat" value="2" />
            <flag name="mid" value="1" />
            <flag name="thin" value="0" />
        </attr>
        <attr name="adult" format="boolean" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>
</resources>

我这里设置了姓名name,性别sex,年龄age,以及特征属性weight(fat,mid,thin内部的3个属性及对应的属性值),还有是否成年adult,和TextView的字体大小textView。

可能这里有人会问,format是什么,里面的单词代表的又是什么意思。

format就是格式,里面的就是这个属性对应的格式,下面列出来大致的格式有:

1. reference:参考某一资源ID,以此类推

(1)属性定义:

<declare-styleable name = “名称”>

<attr name = “background” format = “reference” />

</declare-styleable>

(2)属性使用:

<ImageView

android:layout_width = “42dip”

android:layout_height = “42dip”

android:background = “@drawable/图片ID”

/>

2. color:颜色值

<declare-styleable name = “名称”>

<attr name = “textColor” format = “color” />

</declare-styleable>

3. boolean:布尔值

<declare-styleable name = “名称”>

<attr name = “focusable” format = “boolean” />

</declare-styleable>

4. dimension:尺寸值。注意,这里如果是dp那就会做像素转换

<declare-styleable name = “名称”>

<attr name = “layout_width” format = “dimension” />

</declare-styleable>

5. float:浮点值。

6. integer:整型值。

7. string:字符串

8. fraction:百分数。

9. enum:枚举值

10. flag:是自己定义的,类似于 android:gravity=”top”,就是里面对应了自己的属性值。

11. reference|color:颜色的资源文件。

12.
reference|boolean:布尔值的资源文件

注意://由于reference是从资源文件中获取:所以在XML文件中写这个属性的时候必须 personattr:name=“@string/app_name”这种格式,否则会出错

2.设置好属性文件后,在使用的布局中写相关配置:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:personattr="http://schemas.android.com/apk/res/com.example.declare_styleable"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.example.declare_styleable.PersonView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        personattr:name="@string/person_name" 
        personattr:weight ="fat"
        personattr:adult ="false"
        personattr:textSize="@dimen/text_size"/>

</RelativeLayout>

这里要先应用这个attr:

xmlns:personattr="http://schemas.android.com/apk/res/com.example.declare_styleable"

对应结构是:

xmlns:你自己定义的名称="http://schemas.android.com/apk/res/你程序的package包名"    (我这是com.example.declare_styleable)

包名是配置文件中   package=”com.example.declare_styleable” 这样格式的

之后在布局中自定义的类中设相关属性:

你自己定义的名称:你设的属性 =”属性值”;

3.最后在自定义控件的构造方法中获取你配置的属性值:

public class PersonView extends TextView {
	public PersonView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public PersonView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
	}

	public PersonView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		TypedArray tArray = context.obtainStyledAttributes(attrs,R.styleable.PersonAttr);//获取配置属性
		String name = tArray.getString(R.styleable.PersonAttr_name);<span style="font-family: Arial, Helvetica, sans-serif;">//得到属性name</span>
		int age = tArray.getInt(R.styleable.PersonAttr_age, 15);
		Boolean adult = tArray.getBoolean(R.styleable.PersonAttr_adult, false);
		String str_adult = getAdultStatus(adult);
		int weight = tArray.getInt(R.styleable.PersonAttr_weight, 1);// 默认是中等身材,属性为:1
		String str_weight = getWeightStatus(weight);//获得肥胖属性
		float textSize = tArray.getDimension(R.styleable.PersonAttr_textSize,R.dimen.default_text_size);// 如果你设置为DP等单位,会做像素转换
		tArray.recycle();//回收资源
//		setTextSize(textSize);//设置字体大小
		setText("姓名:" + name + "\n" + "年龄:" + age + "\n" + "是否成年:" + str_adult
				+ "\n" + "体形:" + str_weight);//给自定义的控件赋值
	}
	
	/** 根据传入的值判断是否成年 */
	public String getAdultStatus(Boolean adult ){
		String str_adult = "未成年";
		if (adult) {
			str_adult = "成年";
		}
		return str_adult;
	}
	
	/** 根据传入的值判断肥胖状态 */
	public String getWeightStatus(int weight){
		String str_weight = "中等";
		switch (weight) {
		case 0:
			str_weight = "瘦";
			break;
		case 1:
			str_weight = "中等";
			break;
		case 2:
			str_weight = "肥胖";
			break;
		default:
			break;
		}
		return str_weight;
	}
}

运行后就是:

android 自定义控件 使用declare-styleable进行配置属性(源码角度)「建议收藏」

这样,以后我们就可以根据这个方法,去自定义控件并自定义配置属性了,大大提高了自定义布局的使用效率。


对应的源码下载地址:下载地址

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158672.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 解析Java中文乱码的处理方法

    解析Java中文乱码的处理方法【引自程序犹如人生的博客】为什么说乱码是中国程序员无法避免的话题呢?这个首先要从编码机制上说起,大家都是中文和英文的编码格式不是一样,解码也是不一样的!如果中国的程序员不会遇到乱码,那么只有使用汉语编程。汉语编程是怎么回事,我也不大清楚,应该是前年吧!我一朋友给我介绍汉语编程,怎么不错不错?当时因为学习忙没去关注这个,等我闲了,那个朋友不弄这个,问他,他也不说不大清楚,最后自己对这个学习也不了了之

    2022年7月7日
    48
  • ATM(异步传输模式)是什么?

    ATM(异步传输模式)是什么?异步传输模式(ATM)也称为信元中继(在固定大小的信元中传输数据),通过光纤或双绞线电缆(高速交换)在OSI模型的数据链路层(第2层)运行基于ITU-T宽带综合业务数字网络(B-ISDN)标准的网络技术,该标准是电信业开发的自动取款机可以同时传输各种流量:语音、视频和数据,速度高达每秒155兆比特。它将语音和视频数据转换成数据包,并通过相同的介质传输大数据包数据。自动取款机和TCP。由于两个端点之间使用固定通道路由协议路由,所以/IP是不同的。实时低延迟应用程序,如VoIP和视频,在ATM网络上..

    2022年9月21日
    6
  • Linux开放指定端口命令

    Linux开放指定端口命令1.方式一1、开启防火墙systemctlstartfirewalld2、开放指定端口(比如1935端口)firewall-cmd–zone=public–add-port=1935/tcp–permanent命令含义:–zone#作用域–add-port=1935/tcp#添加端口,格式为:端口/通讯协议–permanent#永久生效,没有此参数重启后失效3、重启防火墙firewall-cmd–reload4、查看..

    2025年9月27日
    5
  • 微信小程序解析富文本标签[通俗易懂]

    微信小程序解析富文本标签[通俗易懂]wxParse方法我踩雷了微信官方文档有个更为便捷的标签<rich-textnodes=”{{}}”></rich-text>

    2022年8月18日
    16
  • 设计一个具有大纯时延时间的一阶惯性环节的计算机控制系统,一阶惯性环节的计算机控制课程设计【参考】.doc…[通俗易懂]

    设计一个具有大纯时延时间的一阶惯性环节的计算机控制系统,一阶惯性环节的计算机控制课程设计【参考】.doc…[通俗易懂]计算机控制课程设计学院自动化科学与工程学生姓名学生学号班级提交日期2013年9月5日指导老师目录课程设计任务题目及要求…………………………………………………课程设计任务对象与论证…………………………………………………控制器的计算、选择以及系统仿真………………………………………硬件电路的设计…………………………………………………………系统框图…………………………

    2022年10月4日
    3
  • centOS缺少libcrypto.so.10文件

    centOS缺少libcrypto.so.10文件步骤一点击此链接步骤二,命令安装dnfinstallcompat-openssl10

    2022年6月22日
    60

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号