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));
}
网友评论