正文
零
一、Typedarray干什么用的
我们在写界面布局的xml时,经常要设置组件的属性,比如常用的
android:id="@+id/id_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
而假如我们需要对自定义的view、viewgroup等等添加自定义的属性呢?就是需要typedarray了。这次我们的例子是给自定义的view添加属性。
二、怎么用Typedarray
1.准备一个自定义的view
code警告
public class ViewWithAttrs extends View {
public ViewWithAttrs(Context context, AttributeSet attrs){
super(context, attrs);
}
}
2.准备(新建)一个arrts.xml
这个xml就是定义属性的地方,我们打开之后添加这个
<resources>
<declare-styleable name="ViewWithAttrs">
<attr name="paint_color" format="color"/>
</declare-styleable>
</resources>
注意第二行的
name="ViewWithAttrs"
,name就是你要添加属性的组件,一定要和view名字相同。
然后就是添加我们想要的属性了,这里我添加了一条属性,属性名是"paint_color",这个是自己定义的,属性类型是:color。
还有其他可选的类型有:
reference 表示引用,参考某一资源ID
string 表示字符串
color 表示颜色值
dimension 表示尺寸值
boolean 表示布尔值
integer 表示整型值
float 表示浮点值
fraction 表示百分数
enum 表示枚举值
flag 表示位运算
3.主角出现:用typedarray获取xml中的属性
通过Contex的obtainStyledAttributes方法创建typedarray,然后用getXXX来获取对应的属性。
show me the code
public class ViewWithAttrs extends View {
private Paint mPaint;
public ViewWithAttrs(Context context, AttributeSet attrs){
super(context, attrs);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setAntiAlias(true);
//首先通过obtainStyledAttributes方法获取typedarray
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.ViewWithAttrs);
//使用typedarray获取对应的属性
int paintColor = typedArray.getColor(R.styleable.ViewWithAttrs_paint_color, Color.BLACK);
//最后的Color.BLACK是没获取到时的默认值
mPaint.setColor(paintColor);
typedArray.recycle();//不要忘记回收!
}
}
这样我们获取到了我们想要的属性,可以在这个View中使用了
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawCircle(200,200,50,mPaint);
}
4.等等,我们还没设置好属性
在MainActivity的布局文件activity_main.xml中添加我们的view并设置好属性
<com.idealcountry.test.ViewWithAttrs
android:id="@+id/id_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:paint_color="@color/blue"/>
这样我们就能在代码中获取xml设置好的paint_color了。//这里我在
color.xml
中注册了一个颜色:color/blue
结果图:
三、最后一点思考
AttributeSet的问题
小德我在写自定义的View时,刚开始定义了一个类的属性用来保存从AttributeSet获取的typedarray,但是手滑了把获取typedarray写到了onDraw()方法里了,测试的时候后发现没有成功获取到xml中定义的属性,通过debug这才知道在onDraw方法中拿到的值是空的,采用了默认值。但是这是为什么呢?
经过查找到layoutInflater这个类才清楚,大概意思就是AttributeSet并不是每个View都分配一个,而是有类似于缓存一样的机制,大家是共用的(大概可以这么理解),所以到ondraw就有可能获取到了不是我们需要的AttributeSet了。
typedarray回收?不存在的
为什么一定要强调回收呢?这东西又不是占了线程,我就不回收能怎么样?(其实不回收的话AS也会一直烦你,说你没有回收)