Android -- MeasureSpec

4929 ワード

カスタムコントロールは、画面上のコントロールのサイズを指定するため、ViewのonMeasureメソッドを書き換えます.
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

onMeasureが入力する2つのパラメータは、前のレベルのコントロールによって入力されるサイズであり、このメソッドを書き換えるときに計算コントロールの実際のサイズを変更し、setMeasuredDimension(int,int)を呼び出して実際のサイズを設定する必要がある場合があります.
onMeasureから送信されたwidthMeasureSpecとheightMeasureSpecは、一般的な寸法数値ではなく、モードと寸法を組み合わせた数値です.
よく使われる3つの関数
int getMode(int measureSpec)//        (  )    (        )
int getSize(int measureSpec)//        (  )     (                )
int makeMeasureSpec(int size,int mode)//                  (  )

取得モード:
int mode = MeasureSpec.getMode(widthMeasureSpec)

寸法:
int size = MeasureSpec.getSize(widthMeasureSpec)

Mode                                                                                                    
modeには3つのケースがあり、値はそれぞれ
MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST
  • MeasureSpec.EXACTLYは正確なサイズで、コントロールのlayout_をwidthまたはlayout_heightが特定の数値に指定した場合andorid:layout_width="50 dip"またはFILL_PARENTは、コントロールのサイズが決まっている場合で、正確なサイズです.
  • MeasureSpec.AT_MOSTは最大サイズで、コントロールのlayout_widthまたはlayout_Height WRAP_として指定CONTENTの場合、コントロールのサイズは一般的にコントロールのサブスペースや内容によって変化します.この場合、コントロールのサイズは親コントロールが許容する最大サイズを超えない限りいいです.よって、このときのmodeはAT_MOST,sizeは親コントロールが許容する最大サイズを与える.
  • MeasureSpec.UNSPECIFIEDはサイズが指定されていませんが、この場合は多くありません.一般的に親コントロールはAdapterViewで、measureメソッドで入力されるモードです.

  • Code                                                                                                    
    コントロールは、縦横スクリーン、画面サイズに応じて適応します.
    @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            if (0 == mRatioWidth || 0 == mRatioHeight) {
                setMeasuredDimension(width, height);
            } else {
                if (width < height * mRatioWidth / mRatioHeight) {
                    setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
                } else {
                    setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
                }
            }
        }
    
        public void fitWindow(int width, int height) {
            if (width < 0 || height < 0) {
                throw new IllegalArgumentException("Size cannot be negative.");
            }
            mRatioWidth = width;//   
            mRatioHeight = height;//   
            requestLayout();//    onMeasure
        }

    天王ゲジトラの分割線です