Android自定义控件的onMesure处理

2019-08-22  本文已影响0人  霁逸lei

1.初始版

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

        private int measureWidth(int widthMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int width;
        int defaultWidth = (int) (marginStart + oneGrid * totalGrids + paint.getStrokeWidth() + stringMaxWidth / 2);
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
            Log.d("RulerView", "EXACTLY,width:" + width + ",default:" + defaultWidth);
        } else if (widthMode == MeasureSpec.AT_MOST) {
            width = Math.min(defaultWidth, widthSize);//防止控件超出父类范围
            Log.d("RulerView", "AT_MOST,width:" + width + ",default:" + defaultWidth);
        } else {
            width = defaultWidth;
            Log.d("RulerView", "UNSPECIFIED,width:" + width + ",default:" + defaultWidth);
        }
        Log.d("RulerView", "width:" + width + ",defaultWidth" + defaultWidth);
        if (defaultWidth != width) {
            oneGrid = (int) ((width - marginStart - paint.getStrokeWidth() - stringMaxWidth / 2) / totalGrids);
        }
        return width;
    }

布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="aaa"/>

                <com.landleaf.everyday.widget.RulerView
                    android:id="@+id/rulePM25Progress"
                    android:layout_centerInParent="true"
                    android:layout_marginStart="50dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:rvLineHeight="5dp"
                    app:rvMarginStart="10dp"
                    app:rvOneGrideWidth="26dp"
                    app:rvPaintStrokeWidth="1"
                    app:rvPaintTextSize="20dp"
                    app:rvMax="200"
                    app:rvMin="0" />
        </RelativeLayout>

        <RelativeLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1">

        </RelativeLayout>


</LinearLayout>

打印如下:
08-22 09:36:03.299 9320-9320/? D/RulerView: UNSPECIFIED,width:327,default:327
08-22 09:36:03.299 9320-9320/? D/RulerView: UNSPECIFIED,width:327,default:327
08-22 09:36:03.299 9320-9320/? D/RulerView: AT_MOST,width:327,default:327
08-22 09:36:03.299 9320-9320/? D/RulerView: EXACTLY,width:327,default:327
08-22 09:36:03.389 9320-9320/? D/RulerView: UNSPECIFIED,width:327,default:327
08-22 09:36:03.389 9320-9320/? D/RulerView: UNSPECIFIED,width:327,default:327
08-22 09:36:03.389 9320-9320/? D/RulerView: AT_MOST,width:327,default:327
08-22 09:36:03.389 9320-9320/? D/RulerView: EXACTLY,width:327,default:327

2.然后发现一个resolveSizeAndState方法可以省去自行判断match_parent、wrap_content等类型

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = (int) (marginStart + oneGrid * totalGrids + paint.getStrokeWidth() + stringMaxWidth / 2);
        int height = (int) (lineHeight * 3 + textHeight + oneGrid * 2);
        //AT_MOST->Math.min(width,MeasureSpec.getSize(widthMeasureSpec));EXACTLY->MeasureSpec.getSize(widthMeasureSpec);UNSPECIFIED->width
        int measuredWidth = resolveSizeAndState(width, widthMeasureSpec, 0);
        if (measuredWidth!=width){
            oneGrid = (int) ((measuredWidth-marginStart-paint.getStrokeWidth()-stringMaxWidth/2)/totalGrids);
        }
        setMeasuredDimension(measuredWidth, resolveSizeAndState(height,heightMeasureSpec,0));
    }
上一篇下一篇

猜你喜欢

热点阅读