首页 > 代码库 > Android 自定义View学习(2)

Android 自定义View学习(2)

上一篇学习了基本用法,今天学一下稍微复杂一点的,先看一下效果图

为了完成上面的效果还是要用到上一期开头的四步


1,属性应该要有颜色,要有速度

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <attr name="speed" format="integer" />
    <attr name="circleColor" format="color" />

    <declare-styleable name="ViewCircle">
        <attr name="speed" />
        <attr name="circleColor" />
    </declare-styleable>

</resources>
如果对这里有什么不了解可以看我上一篇Android 自定义View学习(1)


2, 在构造方法中获得这些属性

	TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.ViewCircle, defStyle, 0);
		int n = a.getIndexCount();
		for (int i = 0; i < n; i++) {
			int attr = a.getIndex(i);
			switch (attr) {
			case R.styleable.ViewCircle_speed:
				mSpeed = a.getInteger(attr, 300);
				break;
			case R.styleable.ViewCircle_circleColor:
				mColor = a.getColor(attr, Color.GREEN);
				break;
			}
		}
		a.recycle();

3,这次我们不重写onMeasure


4,重写onDraw


protected void onDraw(Canvas canvas) {
		// 居中
		canvas.translate(getWidth() / 2, getHeight() / 2);
		// 画出三个圆
		canvas.drawCircle(0, 0, 200, mCircle);
		canvas.drawCircle(0, 0, 180, mCentreCircle);
		canvas.drawCircle(0, 0, 160, mNexCircle);
        //进度
		RectF rectF = new RectF(-180, -180, 180, 180);
		canvas.drawArc(rectF, -90, mProgress, true, mTimer);
        //算出字体所占大小,使其居中
		mLinePaint.getTextBounds(String.valueOf(mProgress), 0,
				String.valueOf(mProgress).length(), rect);
		canvas.drawText(String.valueOf(mProgress), -rect.width() / 2, 0,
				mLinePaint);
		//总进度为六十
		int count = 60;
		//刻度从190--200
		int y = 190;
		Rect rect = new Rect();
		mLinePaint.getTextBounds("00", 0, "00".length(), rect);
		//当i%10==0时画一道刻度线
		for (int i = 0; i < count; i++) {
			if (i % 10 == 0) {
				canvas.drawLine(0, y, 0, 200, mLinePaint);
				canvas.drawText(String.valueOf(i / 10) + "0",
						-rect.width() / 2, 220, mLinePaint);
			}
			canvas.rotate(360 / count, 0, 0);
		}
	}
我们注意一下canvas.drawArc(rectF, -90, mProgress, true, mTimer);

我们传进去的为true效果就是



如果我们传进去false




可以明显的看到差别,没事也可以试试我们这个demo传进去false会是什么效果。


接下来为了让这个进度动起来我们就要用到线程来刷新ui

new Thread() {
			public void run() {
				while (true) {
					mProgress++;
					if (mProgress == 360) {
						mProgress = 0;
					}

					postInvalidate();
					try {
						Thread.sleep(mSpeed);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
		}.start();

这样基本就差不多了。。接下来看看最终效果



项目源码




Android 自定义View学习(2)