在项目的开发中,有时我们需要一个带有弧形的界面来作为背景装饰。
设计这个view的方式比较简单就是自定义绘制的方式,重新写onDraw函数。
/**
* 弧形的view
*/
public class ArcView extends View {
private int mWidth;
private int mHeight;
private int mArcHeight; //圆弧的高度
private int mBgColor; //背景颜色
private int lgColor; //变化的最终颜色
private Paint mPaint; //画笔
private LinearGradient linearGradient;
private Rect rect=new Rect(0,0,0,0);//普通的矩形
private Path path=new Path();//用来绘制曲面
public ArcView(Context context) {
this(context, null);
}
public ArcView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArcView);
mArcHeight = typedArray.getDimensionPixelSize(R.styleable.ArcView_arcHeight, 0);
mBgColor=typedArray.getColor(R.styleable.ArcView_bgColor, Color.parseColor("#303F9F"));
lgColor = typedArray.getColor(R.styleable.ArcView_lgColor, mBgColor);
mPaint = new Paint();
mPaint.setAntiAlias(true);
typedArray.recycle();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// Log.d("----","onSizeChanged");
linearGradient = new LinearGradient(0,0,getMeasuredWidth(),0,
mBgColor,lgColor, Shader.TileMode.CLAMP
);
mPaint.setShader(linearGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置成填充
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mBgColor);
//绘制矩形
rect.set(0, 0, mWidth, mHeight - mArcHeight);
canvas.drawRect(rect, mPaint);
//绘制路径
path.moveTo(0, mHeight - mArcHeight);
path.quadTo(mWidth >> 1, mHeight, mWidth, mHeight - mArcHeight);
canvas.drawPath(path, mPaint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
mWidth = widthSize;
}
if (heightMode == MeasureSpec.EXACTLY) {
mHeight = heightSize;
}
setMeasuredDimension(mWidth, mHeight);
}
}
声明的属性
代码比较简单主要就是使用path绘制路径,增加一个渐变的效果。