美文网首页
Android自定义控件的onMesure处理

Android自定义控件的onMesure处理

作者: 霁逸lei | 来源:发表于2019-08-22 17:39 被阅读0次

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

    相关文章

      网友评论

          本文标题:Android自定义控件的onMesure处理

          本文链接:https://www.haomeiwen.com/subject/cgkosctx.html