android自定义属性的使用
16lz
2021-01-23
我们在做android界面的时候,经常会在xml文件中写如下代码:
<LinearLayout android:layout_width="wrap_content" android:layout_height="fill_parent" android:orientation="horizontal" > <include layout="@layout/layout_menu" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/qq" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="toggleMenu" android:text="button" /> </LinearLayout> </LinearLayout>可以看到这里使用了大量的属性,如android:layout_width,android:layout_height,android:background等等,这里我记录下如何自定义属性。
我们的例子是这样的,使用自定义的属性定义圆的半径和圆心坐标,然后在自定义的MyView(继承自View)中将这个圆画出来
要自定义属性,我们首先需要在xml文件中定义这些属性,在res/values/attrs.xml文件中(如果没有就创建这个文件)加入如下代码:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="MyView"> <attr name="radius" format="float"></attr> <attr name="cx" format="float"></attr> <attr name="cy" format="float"></attr> </declare-styleable> </resources>上面的代码定义了三个属性,radius代表圆的半径,cx和cy代表圆心坐标,在declare-styleable标签中有一个name属性,name属性的值可以随意取,这个值将会在我们做界面时用到。
下面我们定义MyView控件,这个控件继承了View,复写了onDraw方法,在onDraw中画圆,代码如下:
package com.example.testattrs;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;public class MyView extends View {private float radius;//半径private float cx;//圆心横坐标private float cy;//圆心纵坐标private Paint paint;//画圆用到的画笔/**构造方法,在其中获取我们在xml文件中定义的属性,并初始化一些数据*/public MyView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);//设置画笔的属性paint = new Paint();paint.setStrokeWidth(5);paint.setColor(Color.RED);//获取xml中定义的属性TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);//得到属性的总个数final int N = a.getIndexCount();//通过循环获取我们自定义的属性的值for(int i = 0; i < N; i++){int attr = a.getIndex(i);switch(attr){case R.styleable.MyView_radius:radius = a.getFloat(attr, 5.0f);break;case R.styleable.MyView_cx:cx = a.getFloat(attr, 10f);break;case R.styleable.MyView_cy:cy = a.getFloat(attr, 10f);break;}}//TypedArray使用完毕后一定要调用recycle()方法a.recycle();}public MyView(Context context, AttributeSet attrs) {//调用了第一个构造方法this(context, attrs, 0);}public MyView(Context context) {//调用了第一个构造方法this(context, null, 0);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//画出圆canvas.drawCircle(cx, cy, radius, paint);}}可以看到,上面的switch语句中,每一个case后都是R.styleable.MyView_+属性名,这里的MyView_就是我们在属性文件中declare-styleable标签中定义的name属性的值。
然后是Activity中布局文件的使用了,这里先上布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:myview="http://schemas.android.com/apk/res/com.example.testattrs" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.testattrs.MyView android:layout_width="wrap_content" android:layout_height="wrap_content" myview:radius="80.0" myview:cx="100.0" myview:cy="100.0" android:layout_centerHorizontal="true" android:layout_centerVertical="true" /></RelativeLayout>在布局文件中,我们加入了一个自定义的MyView,这里最需要注意的是RelativeLayout中的 xmlns:myview="http://schemas.android.com/apk/res/com.example.testattrs"
因为使用了我们自定义的属性,所以这里要加上新的命名空间,命名空间的写法为:xmlns:[名称]="http://schemas.android.com/apk/res/[控件所在包名]",布局文件中使用自定义属性的方法,就是命名空间+属性名,如myview:radius、myview:cx、myview:cy。
到这里基本上就完成所有代码了,我们运行程序,效果如下:
更多相关文章
- Android Studio的Gradle文件方法说明
- Android的文件系统
- 让Android中的webview支持页面中的文件上传
- Android 文件布局一些细节备忘
- android 线性布局几个属性
- Android布局文件的属性值解析
- Android 文件的保存与读取之自带储存空间