首页 > 技术文章 > Android 自定义控件——自定义属性

gmm283029 2014-12-31 20:09 原文

本文介绍在 Android 当中自定义控件使用自定义属性

本文以下图为例进行讲解   如图:

一个圆,我们自定义一个View ,以画一个圆为例,以圆的半径、颜色、透明值 作为自定义属性来进行讲解


先定义自定义的View,继承View,重载其三个构造方法   Circle.java 

一般我们的自定义属性也是在重载的构造方法中进行初始化,初始化之前我们需要事先定义好属性文件,也可以一边写控件,一边分析需求来添加属性,根据上面提到的需求,我们定义三个属性,半径、颜色、透明度

在values文件夹下新建 attrs.xml 定义三个属性

<span style="font-family:Microsoft YaHei;font-size:12px;"><?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="Circle">
        <attr name="radius" format="dimension" />
        <attr name="color" format="color" />
        <attr name="alpha" format="integer" />
    </declare-styleable>

</resources></span>

declare-styleabke 是专门用来定义属性集合的标签,attr  是具体的属性  attr 中的name是属性的名字,必须是独一无二的,format是属性的类型

常用的属性类型有:

reference       资源类型,通常是@开头,例如@+id/xxxx,@id/xxxxx
string             字符串类型,通常是文字信息
dimension      浮点类型,通常是尺寸度量,单位有很多px,dp,sp,dip等
color              颜色类型,通常是颜色16进制代码,支持ARGB。
boolean         布尔类型,true和false
enum             枚举类型,通常是代表这个属性提供了几种值来进行选择,并且只能选择这几种中的一个
flag                与enum基本没有区别。
integer           整数类型,通常是整数


定义好属性后,我们在 Cricle 的构造方法中初始化属性,初始化属性用TypeArray  根据具体的类型来调用具体的get方法,get到的值就是我们自定义属性设置的值,得不到返回一个默认值,如果不加自定义属性的话,这个圆也是完全可以画出来的,但是你觉得用属性设置参数方便和用java代码来设置参数哪种更加方便,当让是属性的方式了,又快又方便,有省事,有使得java更具有扩展性。

 

public class Circle extends View {

	private Paint mPaint = new Paint();
	private int mColor;
	private int mAlpha;
	private float mRadius;

	public Circle(Context context) {
		super(context);

	}

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

	public Circle(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(attrs);
	}

	public void init(AttributeSet set) {
		TypedArray mTypedArray = getContext().obtainStyledAttributes(set,
				R.styleable.Circle);
		mColor = mTypedArray.getColor(R.styleable.Circle_color, Color.BLACK);
		mRadius = mTypedArray.getDimension(R.styleable.Circle_radius, 50);
		mAlpha = mTypedArray.getInteger(R.styleable.Circle_alpha, 0);
		mTypedArray.recycle();//回收,回收之后属性集attay不可用
		mPaint.setDither(true);
		mPaint.setAntiAlias(true);
		mPaint.setStrokeWidth(10);
		mPaint.setColor(Color.RED);
		mPaint.setAlpha(mAlpha);

	}

	@Override
	protected void onDraw(Canvas canvas) {

		super.onDraw(canvas);
		canvas.drawCircle(600, 600, mRadius, mPaint);
		canvas.save();
	}
}

 

 

java写好之后就要在xml布局文件中给这个圆设置属性了

设置的属性可见 

circle:alpha="255"
circle:radius="@dimen/circle_radius1"
circle:color="@color/circle_red"

circle 和 Cricle类没有关系,这是在xml文件中自己起名字,找到这一行

xmlns:circle="http://schemas.android.com/apk/res/com.example.test"

circle 是自己定义的名字,/apk/res/ 后面换成自已的自定义类的包名,声明完这句之后就可以在自定义控件中加属性了,格式是   自己名字:属性名="参数"

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:circle="http://schemas.android.com/apk/res/com.example.test"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >


    <com.example.test.Circle
        android:id="@+id/circle_1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        circle:alpha="255"
        circle:radius="@dimen/circle_radius1"
        circle:color="@color/circle_red" />

</RelativeLayout>


写好之后运行,图就画出来了,改变参数后重新运行观察效果

如果你还是想在 java 当中改变控件属性,这也都不是问题, 给相应的属性封装 set 方法,设置参数之后调用  invalidate()  重绘界面就ok了






 

推荐阅读