2017-11-12 4 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) 
} 

문제를 해결할 수 있습니까?

관련 문제