Android自定义控件(二)
来源:互联网 发布:如何快速升淘宝等级 编辑:程序博客网 时间:2024/06/06 00:21
上篇文章通过继承view定义了一个圆形控件,在界面上绘制一个圆形,并且根据不同的测量模式设置了不同的大小:自定义控件(一) 。但是我们定义的圆形在界面设计时半径、颜色都已经固定了,本文主要总结如何像原生控件一样,通过在xml文件中设置属性来控制圆形的半径以及颜色,并在圆形中心显示一段文字
首先要定义控件的属性名称,在values文件夹中新建attrs.xml文件,声明属性的名称和类型:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="myView"> <attr name="Text" format="string"/> <attr name="TextColor" format="color"/> <attr name="CircleColor" format="color"/> <attr name="Radius" format="dimension"/> <attr name="TextSize" format="dimension"/> </declare-styleable></resources>
系统提供了TypedArray数据结构来获取自定义属性值,通过TypedArray对象的getString()、getColor()等方法就可以获得xml中设置的属性值,需要注意的是获取完属性值后需要调用TypedArray的recycle方法来完成资源的回收:
TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.myView); mCircleText = ta.getString(R.styleable.myView_Text); mCircleColor = ta.getColor(R.styleable.myView_CircleColor,0); mTextColor = ta.getColor(R.styleable.myView_TextColor,0); radius = ta.getDimension(R.styleable.myView_Radius,50); mTextSize = ta.getDimension(R.styleable.myView_TextSize,15); ta.recycle();
获取到属性之后,通过Paint 的setcolor、setTextSize等函数定义画笔,就可以在屏幕上进行绘制了,我们要实现在圆形绘制一段文字,所以在onDraw中绘制完圆形后,通过调用drawText方法绘制文字,使用这个方法时需要注意参数的含义:
canvas.drawText(text,x,y,paint)
(1)text: 表示要绘制的文字内容
(2)x:表示对齐位置,通过调用paint的setTextAlign(Align align)方法,设置文字的对齐标准,Paint.Align.Center:以中心对齐,Paint.Align.LEFT以左边界对齐,Paint.Align.RIGHT以右边界对齐。
(3)y:表示字符baseline 的位置,这里需要特别注意,y不表示文字中心的高度,而表示文字基线的高度,基线是位于文字下方的,就像在直线上写英文字母一样,那条横线叫做基线。
(2)paint:是绘制的画笔
我们在以圆心位置对齐,绘制文字,所以x以中心对齐,设置宽对齐位置为圆心的位置,若要使文字的中心和圆心重合,需要使文字的基线在圆心下方Text.height()/2的高度才能保证,通过获取问题的外接矩形就可以方便的知道文字的高,从而设置y的大小:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); Rect bounds = new Rect(); mTextPaint.getTextBounds(mCircleText,0,mCircleText.length(),bounds); canvas.drawCircle(width/2,height/2,radius,mPaint); canvas.drawText(mCircleText,width/2,height/2+bounds.height()/2,mTextPaint); }
这样就可以通过xml设置属性,来改变控件的大小、颜色以及文字,但是在设置前,一定要记得引用第三方空间的名字空间,在布局文件中可以看到:
xmlns:android="http://schemas.android.com/apk/res/android
xmlns:custom="http://schemas.android.com/apk/res-auto"
<my.project.ViewTest.myView android:layout_width="match_parent" android:layout_height="200dp" custom:Text="my circle" custom:TextColor="#33ff00" custom:Radius="50dp" custom:CircleColor="#993300" custom:TextSize="20sp" />
效果图如下:
myView源码:
public class myView extends View { private int mCircleColor; private String mCircleText = "defuat"; private int mTextColor; private float mTextSize; private TypedArray ta ; private float radius = 50; private Paint mPaint,mTextPaint; public myView(Context context) { super(context); init(context); } public myView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); ta = context.obtainStyledAttributes(attrs,R.styleable.myView); init(context); } public myView(Context context, AttributeSet attrs) { super(context, attrs); ta = context.obtainStyledAttributes(attrs,R.styleable.myView); init(context); } private void init(Context context){ mCircleText = ta.getString(R.styleable.myView_Text); mCircleColor = ta.getColor(R.styleable.myView_CircleColor,0); mTextColor = ta.getColor(R.styleable.myView_TextColor,0); radius = ta.getDimension(R.styleable.myView_Radius,50); mTextSize = ta.getDimension(R.styleable.myView_TextSize,15); mPaint = new Paint(); mTextPaint = new Paint(); mTextPaint.setTextAlign(Paint.Align.CENTER); mTextPaint.setTextSize(mTextSize); mPaint.setColor(mCircleColor); mTextPaint.setColor(mTextColor); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth(); int height = getHeight(); Rect bounds = new Rect(); mTextPaint.getTextBounds(mCircleText,0,mCircleText.length(),bounds); canvas.drawCircle(width/2,height/2,radius,mPaint); canvas.drawText(mCircleText,width/2,height/2+bounds.height()/2,mTextPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMeasured,heightMeasured; widthMeasured = measureWidth(widthMeasureSpec); heightMeasured = measureHeight(heightMeasureSpec); setMeasuredDimension(widthMeasured,heightMeasured); } private int measureHeight(int measureSpec){ int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if(specMode == MeasureSpec.EXACTLY){ result = specSize; }else{ result = 200; if(specMode == MeasureSpec.AT_MOST){ result = Math.min(result,specSize); } } return result; } private int measureWidth(int measureSpec){ int result = 0; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if(specMode == MeasureSpec.EXACTLY){ result = specSize; }else{ result = 200; if(specMode == MeasureSpec.AT_MOST){ result = Math.min(result,specSize); } } return result; }}
- Android 自定义控件(二)
- android 自定义控件(二)
- android 自定义控件(二)
- Android自定义控件(二)
- Android自定义控件(二)组合控件
- Android自定义控件二
- Android自定义控件<二>
- Android 自定义控件开发入门(二)
- Android 自定义控件开发入门(二)
- android自定义控件二(转载)
- Android常用自定义控件(二)
- android的自定义控件简单(二)
- Android自定义组合控件(二)
- Android深入浅出自定义控件(二)
- Android自定义控件(二):提高篇
- Android--自定义控件解析(二)
- Android自定义控件View(二)继承控件
- Android自定义控件系列二:自定义开关按钮(一)
- Plant CodeForces
- SSL2759 2017年10月6日提高组T2 挖矿(dp)
- 多线程之锁机制
- javaWeb-SAX解析和DOM解析并实现CRUD操作
- 一个HelloWorld程序的生成过程
- Android自定义控件(二)
- 杂志社投稿
- 初学python一些会用到的零件2【参考小甲鱼的书学习】
- 正则中需要转义的特殊字符小结
- struts2获取页面参数多数为null
- android 遍历map的四种方法
- Java实现——排序二叉树的建立与遍历
- 安装nodejs和npm
- nodejs Log4js v2.x配置使用