自定义控件初学篇——onDraw()方法

来源:互联网 发布:叉叉助手类似软件 编辑:程序博客网 时间:2024/06/05 21:06

许多APP上都会有一些比较酷炫美观的动画效果和自定义控件,所以最近研究了一下,又遇到一些疑惑和问题,所以这里记录一下。

自定义控件经常会要提到三个方法,也就是onLayout(),onMeasure()和onDraw()。今天我暂时先讲一下自己对onDraw()方法的学习。

首先我们自定义一个MyView1继承于View类,然后会自动提示我们添加一些方法,这些就不细说了。

在这些提示的方法里面有一个方法:

public MyView1(Context context, AttributeSet attrs, int defStyleAttr) {}
首先我在这个方法里面新建了一个TypeArray对象,通过它来获得MyView1的一些自定义属性。这里我们要新建一个xml格式的文件。
里面的代码如下:
<declare-styleable name="MyView1">    <attr name="left_circle_radius" format="dimension" />    <attr name="left_circle_color" format="color" />    <attr name="top_circle_radius" format="dimension" />    <attr name="top_circle_color" format="color" />    <attr name="right_circle_radius" format="dimension" />    <attr name="right_circle_color" format="color" />    <attr name="bottom_circle_radius" format="dimension" />    <attr name="bottom_circle_color" format="color" /></declare-styleable>
其实也就是定义这个View中需要用到的一些属性,需要注意的是记得写上format的类型,至于为什么,后面我会讲到。在这个View里面我定义了四个圆的半径和颜色。
然后在代码里面我们要获得它们,这里要注意的是获得它们必须是“declare-styleable的name+ attr的name”,例如上面的“MyView1_left_circle_radius",这应该是他们固定的一种格式,不这么写的话会报错的。
除了获得这些属性外,我们还要实例化Paint类的对象。
mPaint = new Paint();mPaint.setAlpha(180); // 透明度mPaint.setStrokeWidth(2); // 画笔宽度mPaint.setAntiAlias(true); // 消除锯齿mPaint.setTextAlign(Paint.Align.CENTER); // 文字居中
上面是Paint类比较常用的几种方法,注释写的很仔细了,所以就不再赘述了。

接下来说onDraw()方法,看到这个方法,大家就知道它跟绘画有关。

onDraw()方法中有一个Canvas类,也就是画布的意思。Canvas类有许多绘画的方法,比如
画圆调用canvas的
drawCircle(left, top, radius, paint);
方法中的属性分别对应要绘制的这个圆最左侧的横坐标,最上侧的纵坐标,半径,和画笔。
画直线调用canvas的             
drawLine(left, top, right, bottom, paint)
方法中的属性也就是这条直线左上右下的四个坐标点,因为宽度已经被paint的setStrokeWidth()方法给固定了。
 画虚线稍微比他们复杂一些,要用到PathEffect类,下面有具体的注释。
PathEffect effects = new DashPathEffect(new float[]{1,2,4,8},1); // 绘制长度1的实线,再绘制长度2的空白,再绘制长度4的实线,再绘制长度8的空白

接下来附上本人写的demo的部分代码:

mPaint.setColor(Color.CYAN);canvas.drawLine(getWidth() - getWidth() / 5 * 4 + 40, getHeight() / 2, getWidth() - getWidth() / 5 - 40, getHeight() / 2, mPaint); // 划线,左,上,右,下,画笔mPaint.setColor(leftCircleColor);/** * 1.Paint.Style.STROKE:描边 * 2.Paint.Style.FILL_AND_STROKE:描边并填充 * 3.Paint.Style.FILL:填充 * 默认FILL */mPaint.setStyle(Paint.Style.FILL_AND_STROKE);canvas.drawCircle(getWidth() - getWidth() / 5 * 4, getHeight() / 2, leftCircleRadius, mPaint); // 画圆,左,上,半径,画笔PathEffect effects = new DashPathEffect(new float[]{1,2,4,8},1); // 绘制长度1的实线,再绘制长度2的空白,再绘制长度4的实线,再绘制长度8的空白mPaint.setPathEffect(effects);mPaint.setColor(topCircleColor);mPaint.setStyle(Paint.Style.STROKE);canvas.drawCircle(getWidth() / 2, getHeight() - getHeight() / 5 * 4, topCircleRadius, mPaint);canvas.drawCircle();
最后就是在Activity里面使用这个MyView1了,首先自然是像那些普通控件一样在activity_main.xml中定义,代码如下:

<com.xue.myview1.MyView1    android:id="@+id/myview1_main"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    xue:left_circle_color="#00FF00"    xue:left_circle_radius="30dp"    xue:top_circle_color="#303F9F"    xue:top_circle_radius="30dp"    xue:right_circle_color="#FF4081"    xue:right_circle_radius="30dp"    xue:bottom_circle_color="#FFFF00"    xue:bottom_circle_radius="30dp"/>
,然后在Activity定义MyView1的对象并找到就好了。

然而,在开发完成的时候遇到了下面这个问题:

Error:Execution failed for task ':app:processDebugResources'.> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:\adt-bundle-windows-x86_64-20140624\sdk\build-tools\23.0.1\aapt.exe'' finished with non-zero exit value 1
这个问题困扰了我几个小时,刚开始的时候以为是

xmlns:xue="http://schemas.android.com/apk/res-auto"这条语句的问题,可是把res-auto换成对应的包名还是没有用,也仔细查看过语句,可是由于报错的信息中没有定位到错误的地方。最后还是解决了,我发现是导致这个报错的原因如下:
1、xml文件中"xue:"后面定义的属性和attrs中的属性有出入;
2、"30dp"和”#000000"和属性的类型有出入,开始的时候没有写format="color"和format="dimension",而代码中定义的是

private int leftCircleColor = Color.WHITE;private float leftCircleRadius = 40.0f;leftCircleColor = a.getColor(attr, leftCircleColor);leftCircleRadius = a.getDimension(attr, leftCircleRadius);

这就是我初次学习自定义View的一些小知识的理解和使用。

0 0