2017-11-12 6 views
0

幅と高さが常に等しいことを確認したいと考えています。カスタムビューで異常な動作が発生する

xmlで指定した高さと幅をユーザーが定義すると、小さい方が選択されます。例えば

<com.mmmmar.ControlView 
    android:layout_width="100dp" 
    android:layout_height="200dp" 
    android:background="#f00" /> 

それがうまく実行します。 image that app runs well

ただし、高さよりも幅を大きくすると、予期せず実行されます。 緑色のブロックは、このビューで描画するものです。赤色のブロックは、表示領域を示すためにxmlに設定した背景です。ここ

<com.mmmmar.ControlView 
    android:layout_width="200dp" 
    android:layout_height="100dp" 
    android:background="#f00" /> 

iamge that app runs wrong

私のコードは、あなたが計算した後測定した寸法を設定する必要はありません

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
@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) 
} 

問題を修正しますか。

関連する問題