简体   繁体   English

自定义视图中的异常行为

[英]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" />

it run well. 运行良好。 应用运行良好的图像

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" />

iamge该应用程序运行错误

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM