前言:
当Android系统原生的控件无法满足我们的需求时,我们就可以完全创建一个新的自定义View来实现需要的功能。创建一个自定义View,难点在于绘制控件和实现交互,这也是评价一个自定义View优劣的标准之一。通常需要继承View()类,并重写他的onDraw(),onMeasure()方法来实现绘制逻辑,同时重写onTouchEvent()等触控事件来实现交互逻辑。当然,我们还可以实现组合控件的方式那样,通过引入自定义属性,丰富自定义Viewd的可自定义Viewd的可定制性。
一 弧线展示图
上面的图片非常清楚的展示一个项目所占的比例,简洁明了。因此,实现这样一个自定义View用在我们的程序中,可以让整个程序实现比较清晰的数据展示效果。那么该如何创建一个这样的自定义View呢?很明显,这个自定义View分为三个部分,分别是中间的圆形,中间展示的文字和外圈的弧线。既然有了这样的思路,只要在onDraw()方法中一个个去绘制就可以了。这里为了方便,我们把View的绘制长度直接设置为屏幕的宽度。首先,在初始的时候,设置好三种图形的参数。园的代码如下所示:
mCircleXY = length / 2; mRadius = (float) (length * 0.5 / 2);绘制弧线,需要指定其椭圆的外接矩形,代码如下所示。
mArcRectF = new RectF( (float) (length * 0.1), (float) (length * 0.1), (float) (length * 0.9), (float) (length * 0.9));
接下来,我们就可以在onDraw()方法中进行绘制了,代码如下所示。
// 绘制圆 canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint); // 绘制弧线 canvas.drawArc(mArcRectF, 270, mSweepAngle, false, mArcPaint); // 绘制文字 canvas.drawText(mShowText, 0, mShowText.length(), mCircleXY, mCircleXY + (mShowTextSize / 4), mTextPaint);
当然,对于这个简单的view,有一些方法可以让调用者来设置不同的状态值,代码如下所示。
public void setSweepValue(float sweepValue) { if (sweepValue != 0) { mSweepValue = sweepValue; } else { mSweepValue = 25; } this.invalidate(); }
二 音频条形图
在上面的图片中,我们也看到了这个简单的案例,由于只是演示一下自定义View的用法,我们就不去真实的监听音频输入了,随机模拟一些数字即可。这个实例比上面的比例图稍微复杂一些,主要复杂在绘制的坐标计算和动画效果上,我们先来看一下,要实现这样一个条形图,相信大家应该可以很快找到思路,也就是绘制一个个的矩形,每个矩形之间稍微偏移一点距离即可。如下展示了一种坐标的计算方法。
@Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); for(int i = 0;i< mRectCount;i++){ canvas.drawRect( (float) (mWidth * 0.4 / 2 + mRectWidth * i + offset), currentHeight, (float) (mWidth * 0.4 / 2 + mRectWidth * (i + 1)), mRectHeight, mPaint); } }
如上代码中我们通过循环创建了这些小的矩形,其中currentHeight就是每个小矩形的高,通过坐标的不断偏移,就绘制出了这些静态的小矩形。下面我们再让这些小矩形的高度进行随机变化,通过Math.random()方法来随机改变这些高度值,并赋值给currentHeight,代码如下所示:
mRandom =Math.random(); float currentHeight=(float)(mRectHeight*mRandom);
postInvalidateDelayed(300);
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mWidth = getWidth(); mRectHeight = getHeight(); mRectWidth = (int)(mWidth * 0.6 / mRectCount); mLinearGradient = new LinearGradient(0, 0, mRectWidth, mRectHeight, Color.YELLOW, Color.BLUE, Shader.TileMode.CLAMP); mPaint.setShader(mLinearGradient); }
源码地址:http://blog.csdn.net/qq_31307919/article/details/51098418