[英]strange behavior in custom view
I want to make a view that it's width and height is always equal. 我想证明它的宽度和高度始终相等。
when user define a specfied height and width in xml, it chooses a smaller one. 当用户在xml中定义指定的高度和宽度时,它会选择较小的高度和宽度。
for example: 例如:
<com.mmmmar.ControlView
android:layout_width="100dp"
android:layout_height="200dp"
android:background="#f00" />
However, when I make width lager than height, It runs unexpectedly. 但是,当我使宽度大于高度时,它会意外运行。 green block is something I draw on this view, red block is the background I set in xml to indicate the area of view.
绿色块是我在此视图上绘制的东西,红色块是我在xml中设置的用于指示视图区域的背景。
<com.mmmmar.ControlView
android:layout_width="200dp"
android:layout_height="100dp"
android:background="#f00" />
here is my code 这是我的代码
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;
}
}
@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;
}
You do not need to set measured dimension after calculating. 计算后无需设置测量尺寸。
@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)
}
Would be fix your problem. 将解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.