我想知道它的宽度和高度总是相等的。
当用户在xml中定义指定的高度和宽度时,它会选择较小的一个。
例如:
<com.mmmmar.ControlView
android:layout_width="100dp"
android:layout_height="200dp"
android:background="#f00" />
它运行良好。
然而,当我使宽度大于高度时,它会意外地运行。 绿色块是我在这个视图上绘制的,红色块是我在xml中设置的背景,用于指示视图区域。
<com.mmmmar.ControlView
android:layout_width="200dp"
android:layout_height="100dp"
android:background="#f00" />
这是我的代码
public class ControlView extends View {
private final static int DEFAULT_SIZE = 200;
private int mDrawRadius;
private Paint mPaint;
public ControlView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// configure paint
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
mPaint = paint;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int size = dp2px(DEFAULT_SIZE, getContext());
int width = calculateSpec(widthMeasureSpec, size);
int height = calculateSpec(heightMeasureSpec, size);
int radius = Math.min(width, height);
// width should equal height.
setMeasuredDimension(radius, radius);
mDrawRadius = radius;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = mPaint;
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(0, 0, mDrawRadius, mDrawRadius, paint);
}
public int dp2px(float dp, Context context) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
public int calculateSpec(int measureSpec, int defaultSize) {
int mode = View.MeasureSpec.getMode(measureSpec);
int size = View.MeasureSpec.getSize(measureSpec);
int realSize;
if (mode == View.MeasureSpec.EXACTLY) {
realSize = size;
} else {
// For Mode :UNSPECIFIED and AT_MOST
realSize = Math.min(size, defaultSize);
}
return realSize;
}
}
答案 0 :(得分:0)
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int size = dp2px(DEFAULT_SIZE, getContext());
int width = calculateSpec(widthMeasureSpec, size);
int height = calculateSpec(heightMeasureSpec, size);
int radius = Math.min(width, height);
// width should equal height.
setMeasuredDimension(radius, radius);
mDrawRadius = radius;
}
计算后无需设置测量尺寸。
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Your logic comes here to pick smallest border
super.onMeasure(smallest_border_that_you_pick,smallest_border_that_you_pick)
}
会解决你的问题。