对于自定义属性,遵循以下几步,就可以实现:

  1. 自定义一个CustomView(extends View )类
  2. 编写res/values/attrs.xml,在其中编写styleable和item等标签元素
  3. 在布局文件中CustomView使用自定义的属性(注意namespace)
  4. 在CustomView的构造方法中通过TypedArray获取

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:background="@color/color_white"    android:gravity="center_horizontal"    android:orientation="vertical">              <com.demo.RoundCornerProgress                    android:id="@+id/progressBar"                    android:layout_width="300dp"                    android:layout_height="13dp"                    app:rcMax="100000"                    app:rcBackgroundColor="#dedede"                    app:rcProgressColor="#fcc329"                    app:rcRadius="6.5dp" />LinearLayout>

com.demo.RoundCornerProgress是自定义的ProgressBar,布局文件中

app:rcMax="100000"app:rcBackgroundColor="#dedede"app:rcProgressColor="#fcc329"app:rcRadius="6.5dp"

是自定义的属性。

app是命名空间,自己可以随便命名其他名字,用来加在自定义属性前面。

xmlns:android=”http://schemas.android.com/apk/res/android

声明xml命名空间。xmlns意思为“xml namespace”.冒号后面是给这个引用起的别名。
schemas是xml文档的两种约束文件其中的一种,规定了xml中有哪些元素(标签)、元素有哪些属性及各元素的关系,当然从面向对象的角度理解schemas文件可以认为它是被约束的xml文档的“类”或称为“模板”。

早期或简单的xml用的是另一种约束,称为DTD,这东西大家天天都见到。html/xhtml中都存在(早期的html可能没有),如” html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd“。

现在大部分xml文档的约束都换成schema了,原因是schema本身也是xml,二schema扩展性强。

rcMax、rcProgress等就是xml里面自己命名的。

<?xml version="1.0" encoding="utf-8"?><resources xmlns:android="http://schemas.android.com/apk/res/android">        <declare-styleable name="RoundCornerProgress">        <attr name="rcReverse" format="boolean"/>        <attr name="rcProgress" format="float"/>        <attr name="rcMax" format="float"/>        <attr name="rcSecondaryProgress" format="float"/>        <attr name="rcBackgroundPadding" format="dimension"/>        <attr name="rcRadius" format="dimension"/>        <attr name="rcProgressColor" format="color"/>        <attr name="rcSecondaryProgressColor" format="color"/>        <attr name="rcBackgroundColor" format="color"/>    declare-styleable>resources>

其中的format的意义和可取的值有以下一些:

  • reference:表示引用,参考某一资源ID
    (1)属性定义:
    (2)属性使用:
android:layout_width = "42dip"android:layout_height = "42dip"android:background = "@drawable/图片ID"/>
  • color:颜色值
  • boolean:布尔值
  • dimension:尺寸值。注意,这里如果是dp那就会做像素转换
  • float:浮点值。
  • integer:整型值。
  • string:字符串
  • fraction:百分数。
  • enum:枚举值
  • flag:是自己定义的,类似于 android:gravity=”top”,就是里面对应了自己的属性值。
  • reference|color:颜色的资源文件。 12.reference|boolean:布尔值的资源文件

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


接着就可以在自定义控件中获取了

context通过调用obtainStyledAttributes方法来获取一个TypeArray,然后由该TypeArray来对属性进行设置
obtainStyledAttributes方法有三个,我们最常用的是有一个参数的obtainStyledAttributes(int[] attrs),其参数直接styleable中获得
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);
调用结束后务必调用recycle()方法,否则这次的设定会对下次的使用造成影响

public void setupStyleable(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundCornerProgress);        radius = (int) typedArray                .getDimension(R.styleable.RoundCornerProgress_rcRadius, dp2px(DEFAULT_PROGRESS_RADIUS));        padding = (int) typedArray.getDimension(R.styleable.RoundCornerProgress_rcBackgroundPadding,                dp2px(DEFAULT_BACKGROUND_PADDING));        isReverse = typedArray.getBoolean(R.styleable.RoundCornerProgress_rcReverse, false);        max = typedArray.getFloat(R.styleable.RoundCornerProgress_rcMax, DEFAULT_MAX_PROGRESS);        progress = typedArray.getFloat(R.styleable.RoundCornerProgress_rcProgress, DEFAULT_PROGRESS);        secondaryProgress = typedArray.getFloat(R.styleable.RoundCornerProgress_rcSecondaryProgress,                DEFAULT_SECONDARY_PROGRESS);        int colorBackgroundDefault = context.getResources().getColor(                R.color.round_corner_progress_bar_background_default);        colorBackground = typedArray                .getColor(R.styleable.RoundCornerProgress_rcBackgroundColor, colorBackgroundDefault);        int colorProgressDefault = context.getResources().getColor(R.color.round_corner_progress_bar_progress_default);        colorProgress = typedArray.getColor(R.styleable.RoundCornerProgress_rcProgressColor, colorProgressDefault);        int colorSecondaryProgressDefault = context.getResources().getColor(                R.color.round_corner_progress_bar_secondary_progress_default);        colorSecondaryProgress = typedArray.getColor(R.styleable.RoundCornerProgress_rcSecondaryProgressColor,                colorSecondaryProgressDefault);        typedArray.recycle();        initStyleable(context, attrs);    }

在控件构造方法中调用该方法就能获取到值了

public RoundCornerProgressBar(Context context, AttributeSet attrs) {            setup(context, attrs);   }

AttributeSet中的确保存的是该View声明的所有的属性,并且可以通过它去获取(自定义的)属性。

public CustomView(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);        }    }

就能打印出所有属性。

attrName = layout_width , attrVal = 300.0dip
attrName = layout_height , attrVal = 13.0dip
attrName = app:rcMax , attrVal = 100000.0

更多相关文章

  1. Android通过startService实现文件批量下载
  2. Android获取系统储存以及内存信息的方法(一)
  3. Android插件DSL参考
  4. Android中使用系统相机进行拍照并获取高清照片(一)
  5. Android(安卓)Studio3.0 Kotlin工程问题集
  6. Android第三方授权(新浪微博篇)
  7. Android(安卓)Studio创建Xposed Module项目的正确姿势。
  8. Android动画常用公共属性详解
  9. android permiss manager (安全软件获取权限 禁用 可用 提示状态)

随机推荐

  1. Android中各种JAVA包的功能描述
  2. Android中Input型输入设备驱动原理分析
  3. Android,谁动了我的内存(转)
  4. Android安全机制
  5. Android中数据存储----SQLite数据库
  6. 第十章、Android的消息机制
  7. Android屏幕密度(Density)和分辨率的关系
  8. Android之NDK开发修补版
  9. 【译】Google官方推出的Android架构组件
  10. Android中解决图像解码导致的OOM问题