设计部要求背景实现一个背景边框带圆弧的效果:
所以想着用自定义控件画一个背景。
为了方便,继承的是LinearLayout,在onMeasure中先获取控件宽高:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = 0;
int measuredHeight = 0;
final int childCount = getChildCount();
measureChildren(widthMeasureSpec, heightMeasureSpec);
int widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpaceSize = MeasureSpec.getSize(heightMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (childCount == 0) {
setMeasuredDimension(0, 0);
} else if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
final View childView = getChildAt(0);
measuredWidth = childView.getMeasuredWidth() * childCount;
measuredHeight = childView.getMeasuredHeight();
setMeasuredDimension(measuredWidth, measuredHeight);
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
final View childView = getChildAt(0);
measuredHeight = childView.getMeasuredHeight();
setMeasuredDimension(widthSpaceSize, childView.getMeasuredHeight());
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
final View childView = getChildAt(0);
measuredWidth = childView.getMeasuredWidth() * childCount;
setMeasuredDimension(measuredWidth, heightSpaceSize);
}
mWidthMode = measuredWidth;
mHeightMode = measuredHeight;
Log.i("yan", "高度:" + mWidthMode + "宽度:" + mHeightMode);
}
因为是viewgroup,所以给控件绘图的方法写在dispatchDraw方法中
@Override
protected void dispatchDraw(Canvas canvas) {
initDrawBg(canvas);//放在super前是后景,相反是前景,前景会覆盖子布局
super.dispatchDraw(canvas);
}
用path画出路径,然后用paint填充。
private void initDrawBg(Canvas canvas) {
canvas.drawColor(Color.parseColor("#00FFFFFF"));//绘制透明色
int size = 26;
mPaint = new Paint();
mpath = new Path();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mpath.lineTo(mWidthMode - size, 0);
RectF rectF1 = new RectF(mWidthMode - size, -size, mWidthMode + size, size);
mpath.arcTo(rectF1, -180, -90);
mpath.lineTo(mWidthMode, mHeightMode - size);
RectF rectF2 = new RectF(mWidthMode - size, mHeightMode - size, mWidthMode + size, mHeightMode + size);
mpath.arcTo(rectF2, -90, -90);
mpath.lineTo(size, mHeightMode);
RectF rectF3 = new RectF(-size, mHeightMode - size, size, mHeightMode + size);
mpath.arcTo(rectF3, 0, -90);
mpath.lineTo(0, size);
RectF rectF4 = new RectF(-size, -size, size, size);
mpath.arcTo(rectF4, -270, -90);
mpath.lineTo(size, 0);
mpath.close();
canvas.drawPath(mpath, mPaint);
}
addArc和arcTo都是添加圆弧到path中,不过他们之间还是有区别的:addArc是直接添加圆弧到path中,而arcTo会判断要绘制圆弧的起点与绘制圆弧之前path中最后的点是否是同一个点,如果不是同一个点的话,就会连接两个点。使用accTo可让白色填充。
完整代码 :
package com.example.myapplication.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
/**
* 反圆角
*/
public class BGRelactLayout extends LinearLayout {
private int mWidthMode;
private int mHeightMode;
private Paint mPaint;
private Path mpath;
public BGRelactLayout(Context context) {
super(context);
}
public BGRelactLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BGRelactLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Log.i("yan", w + "," + h + "," + oldw + "," + oldh);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = 0;
int measuredHeight = 0;
final int childCount = getChildCount();
measureChildren(widthMeasureSpec, heightMeasureSpec);
int widthSpaceSize = MeasureSpec.getSize(widthMeasureSpec);
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSpaceSize = MeasureSpec.getSize(heightMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
if (childCount == 0) {
setMeasuredDimension(0, 0);
} else if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
final View childView = getChildAt(0);
measuredWidth = childView.getMeasuredWidth() * childCount;
measuredHeight = childView.getMeasuredHeight();
setMeasuredDimension(measuredWidth, measuredHeight);
} else if (heightSpecMode == MeasureSpec.AT_MOST) {
final View childView = getChildAt(0);
measuredHeight = childView.getMeasuredHeight();
setMeasuredDimension(widthSpaceSize, childView.getMeasuredHeight());
} else if (widthSpecMode == MeasureSpec.AT_MOST) {
final View childView = getChildAt(0);
measuredWidth = childView.getMeasuredWidth() * childCount;
setMeasuredDimension(measuredWidth, heightSpaceSize);
}
mWidthMode = measuredWidth;
mHeightMode = measuredHeight;
Log.i("yan", "高度:" + mWidthMode + "宽度:" + mHeightMode);
}
@Override
protected void dispatchDraw(Canvas canvas) {
initDrawBg(canvas);//放在super前是后景,相反是前景,前景会覆盖子布局
super.dispatchDraw(canvas);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
private void initDrawBg(Canvas canvas) {
canvas.drawColor(Color.parseColor("#00FFFFFF"));//绘制透明色
int size = 26;
mPaint = new Paint();
mpath = new Path();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mpath.lineTo(mWidthMode - size, 0);
RectF rectF1 = new RectF(mWidthMode - size, -size, mWidthMode + size, size);
mpath.arcTo(rectF1, -180, -90);
mpath.lineTo(mWidthMode, mHeightMode - size);
RectF rectF2 = new RectF(mWidthMode - size, mHeightMode - size, mWidthMode + size, mHeightMode + size);
mpath.arcTo(rectF2, -90, -90);
mpath.lineTo(size, mHeightMode);
RectF rectF3 = new RectF(-size, mHeightMode - size, size, mHeightMode + size);
mpath.arcTo(rectF3, 0, -90);
mpath.lineTo(0, size);
RectF rectF4 = new RectF(-size, -size, size, size);
mpath.arcTo(rectF4, -270, -90);
mpath.lineTo(size, 0);
mpath.close();
canvas.drawPath(mpath, mPaint);
}
}
附上程序员交流和福利发放群,平时给程序员发发福利:725030150
951

被折叠的 条评论
为什么被折叠?



