當原生控制項不符合需求,並且進行拓展或組合也無濟於事的時候,就需要自己來繪製一個控制項了。<! more 全新的View 通過源碼,我們可以看到所有的控制項都是通過繼承View類來實現的。所以,我們要創建全新的控制項,也是要通過繼承View來實現。 案例 案例同樣來自《Android群英傳》。 繪製圓弧文本 ...
當原生控制項不符合需求,並且進行拓展或組合也無濟於事的時候,就需要自己來繪製一個控制項了。
全新的View
通過源碼,我們可以看到所有的控制項都是通過繼承View類來實現的。所以,我們要創建全新的控制項,也是要通過繼承View來實現。
案例
案例同樣來自《Android群英傳》。
繪製圓弧文本
唯恐文字描述有誤,先放上效果圖看看效果
public class CircleProgressView extends View {
private int mMeasureHeigth;
private int mMeasureWidth;
private Paint mCirclePaint;
private float mCircleXY;
private float mRadius;
private Paint mArcPaint;
private RectF mArcRectF;
private float mSweepAngle;
private float mSweepValue = 66;
private Paint mTextPaint;
private String mShowText;
private float mShowTextSize;
public CircleProgressView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CircleProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircleProgressView(Context context) {
super(context);
}
@Override
protected void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
mMeasureWidth = MeasureSpec.getSize(widthMeasureSpec);
mMeasureHeigth = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mMeasureWidth, mMeasureHeigth);
initView();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 繪製圓
canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
// 繪製弧線
canvas.drawArc(mArcRectF, 270, mSweepAngle, false, mArcPaint);
// 繪製文字
canvas.drawText(mShowText, 0, mShowText.length(),
mCircleXY, mCircleXY + (mShowTextSize / 4), mTextPaint);
}
private void initView() {
float length = 0;
if (mMeasureHeigth >= mMeasureWidth) {
length = mMeasureWidth;
} else {
length = mMeasureHeigth;
}
mCircleXY = length / 2;
mRadius = (float) (length * 0.5 / 2);
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(getResources().getColor(
android.R.color.holo_blue_bright));
mArcRectF = new RectF(
(float) (length * 0.1),
(float) (length * 0.1),
(float) (length * 0.9),
(float) (length * 0.9));
mSweepAngle = (mSweepValue / 100f) * 360f;
mArcPaint = new Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setColor(getResources().getColor(
android.R.color.holo_blue_bright));
mArcPaint.setStrokeWidth((float) (length * 0.1));
mArcPaint.setStyle(Style.STROKE);
mShowText = setShowText();
mShowTextSize = setShowTextSize();
mTextPaint = new Paint();
mTextPaint.setTextSize(mShowTextSize);
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
private float setShowTextSize() {
this.invalidate();
return 50;
}
private String setShowText() {
this.invalidate();
return "ANDROID SKILL";
}
public void forceInvalidate() {
this.invalidate();
}
public void setSweepValue(float sweepValue) {
if (sweepValue != 0) {
mSweepValue = sweepValue;
} else {
mSweepValue = 25;
}
this.invalidate();
}
}
動態音頻條形圖
public class CustomView extends View {
private int mRectCount;
private Paint mPaint;
private int mRectHeight;
private int offset = 5;
private int mWidth;
private double mRandom;
private int mRectWidth;
public CustomView(Context context) {
super(context);
initView();
}
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}
public CustomView(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs,defStyleAttr);
initView();
}
private void initView() {
mPaint = new Paint();
mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.FILL);
mRectCount = 12;
}
@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);
LinearGradient mLinearGradient = new LinearGradient(
0,
0,
mRectWidth,
mRectHeight,
Color.RED,
Color.BLUE,
Shader.TileMode.CLAMP
);
mPaint.setShader(mLinearGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < mRectCount; i++) {
mRandom = Math.random();
//每個條形的高
float currentHeight = (float) (mRectHeight * mRandom);
canvas.drawRect(
(float) (mWidth * 0.4 / 2 + mRectWidth * i + offset),
currentHeight,
(float) (mWidth * 0.4 / 2 + mRectWidth * (i + 1)),
mRectHeight,
mPaint);
}
//延遲重繪
postInvalidateDelayed(300);
}
}
自己創建的控制項用法與原生控制項大同小異,可進行參照。
更多文章也可關註我的靜態博客,更新相對會優先些傳送門