• Android 属性自定义及使用获取浅析


    一、概述

    相信你已经知道,Android 可使用 XML 标签语言进行界面的定义。每个标签中有一个一个的属性,这些属性有相应的属性值。例如:

    <cn.neillee.composedmenu.RotatingArcMenu
    	android:id="@+id/ram2"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:background="?attr/barBgColor"
    	app:position="left_bottom"
    	app:radius="150dp"/>
    

    有两点可以注意到:

    • 其一,在某个自定义 ViewGroup 中,有两个自定义属性 positionradius,与其他属性不同的是,这两个属性的命名空间为 app

    • 其二,系统属性 background 的属性值为 ?attr/barBgColor

    二、详细介绍

    2.1 自定义属性

    这里介绍

    app:position="left_bottom"
    app:radius="150dp"
    

    的使用。

    自定义属性常见于自定义的 View 中,让我们还是以概述中的代码作为例子。自定义属性及其属性值在 /values/attr.xml 中有如下定义:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    
        <attr name="position">
            <enum name="left_top" value="0"/>
            <enum name="left_bottom" value="1"/>
            <enum name="right_top" value="2"/>
            <enum name="right_bottom" value="3"/>
        </attr>
        <attr name="radius" format="dimension"/>
    
        <declare-styleable name="ComposedMenu">
            <attr name="position"/>
            <attr name="radius"/>
        </declare-styleable>
    </resources>
    

    在该文件中,枚举了 position 有四个属性值,并为每个属性值提供了不同的 value 值作区分。而 radius 定义为 dimension 引用,表示其值须为 dimension 类型的值。类似地,还有如有其他类型,参考文章 【Android】Android自定义属性,attr format取值类型

    接下来如何获取自定义属性值就成了关键。我在自定义 ViewGroup 中使用如下代码获取到用户在 layout 文件中,自定义 ViewGroup 标签下使用到的值。

    private static final int LEFT_TOP = 0;
    private static final int LEFT_BOTTOM = 1;
    private static final int RIGHT_TOP = 2;
    private static final int RIGHT_BOTTOM = 3;
    
    protected static final int DEFAULT_RADIUS = 150;
    protected static final int DEFAULT_POSITION = RIGHT_BOTTOM;
    
    protected int mRadius;
    
    ...
    public RotatingArcMenu(Context context, AttributeSet attrs, int defStyleAttr) {
    	TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ComposedMenu, defStyleAttr, 0);
    	int pos = a.getInt(R.styleable.ComposedMenu_position, DEFAULT_POSITION);
    	mRadius = (int) a.getDimension(R.styleable.ComposedMenu_radius, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_RADIUS, getResources().getDisplayMetrics()));
    	a.recycle();// 使用完后记得回收
    }
    

    2.2 获取系统属性

    这里介绍 android:background="?attr/barBgColor" 属性的定义与获取。

    我之所以如此定义,是为了使得 背景色 能够随着应用的主题切换而变化,最简单的例子就是 夜间模式
    首先,我在 values/attr.xml 文件中对 barBgColor 进行定义:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
    	...
        <attr name="barBgColor" format="color"/>
    </resources>
    

    其次,在 values/styles.xml 中对该属性值进行了定义:

    <resources>
    
        <style name="AppDayTheme" parent="Theme.AppCompat.Light.NoActionBar">
    		<item name="barBgColor">@color/ZHIHUBlue</item>
    	</style>
    	<style name="AppNightTheme" parent="Theme.AppCompat.Light.NoActionBar">
    		<item name="barBgColor">#263238</item>
    	</style>
    </resources>
    

    最后,我在控件的属性中对该属性值进行了使用

    <cn.neillee.composedmenu.RotatingArcMenu
    	android:id="@+id/ram2"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:background="?attr/barBgColor"
    	app:position="left_bottom"
    	app:radius="150dp"/>
    

    需要说明的是,可以不再控件属性中使用自定义的属性值,可在代码中进行获取与设置。如:

    TypedValue typedValue = new TypedValue();
    mContext.getTheme().resolveAttribute(R.attr.barBgColor, typedValue, true);
    mRotatingArcMenu.setBackgroundColor(typedValue.data);
    

    这里使用到了 TypedValue 这个类。

    2.3 关于 TypedValue

    详细介绍见官网:
    https://developer.android.com/reference/android/util/TypedValue.html

    此处我仅对我在上一小节中的使用做简单介绍。在使用过程中,我观察到在不同主题下,TypedValue 读取到的值如下:

    在 DayTheme 中,由于我定义的是 @color/ZHIHUBlue ,对color的引用即 resourceId。因此,typedValue.resourceId 有值,且直接等效于 R.color.ZHIHUBlue,typedValue.type=TYPE_INT_COLOR_RGB8,表示 typedValue.data 有值,为8位的颜色代码值(#rrggbb)。

    在 NightTheme 中,由于我定义的是 #263238,颜色代码值。因此,TypedValue.resourceId 无值,但 typedValue.type=TYPE_INT_COLOR_RGB8,表示 typedValue.data 有值,为8位的颜色代码(#rrggbb)。

    此文在我的 Github Pages 上同步发布,地址为:Android-属性自定义及使用获取浅析

  • 相关阅读:
    gdb 调试器的使用
    vi 的基本操作
    Makefile
    gcc
    动态内存分配
    Linux常用命令
    文件基本操作
    linux的启动配置文件(grub)
    Hello IT
    Val简介(来源维基百科)
  • 原文地址:https://www.cnblogs.com/neillee/p/6931954.html
Copyright © 2020-2023  润新知