Android自定义控件继承view,设置具体dp值和match_prarent后,控件不显示的问题 自定义了一个半圆进度条控件,代码如下: ``` package com.galen.calculator.common.view; import android.animation.ValueAnimator; import android.annotation.TargetApi; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Typeface; import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.animation.OvershootInterpolator; import com.galen.calculator.R; public class CustomView extends View { private static final String TAG="CustomView"; //画笔 private Paint paint; private RectF oval; //圆弧颜色 private int roundColor; //进度颜色 private int progressColor; //文字内容 private boolean textIsShow; //字体大小 private float textSize = 14; //文字颜色 private int textColor; //最大进度 private int max = 100; //当前进度 private int progress = 15; //圆弧宽度 private int roundWidth = 10; private int viewWidth; //宽度--控件所占区域 private float nowPro = 0;//用于动画 private int defaultPadding=40; private ValueAnimator animator; public CustomView(Context context) { this(context, null); } public CustomView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CustomView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initAttrs(attrs, context,defStyleAttr); } private void initAttrs(AttributeSet attr, Context context, int defStyleAttr) { TypedArray array = context.obtainStyledAttributes(attr, R.styleable.CustomView,defStyleAttr,0); roundColor = array.getColor(R.styleable.CustomView_roundColor, Color.BLACK);//环形颜色 progressColor = array.getColor(R.styleable.CustomView_progressColor, Color.RED);//进度颜色 textIsShow = array.getBoolean(R.styleable.CustomView_textIsShow, false);//文字 textSize = array.getDimension(R.styleable.CustomView_textSize, 14);//文字大小 textColor = array.getColor(R.styleable.CustomView_textColor, Color.BLACK);//文字颜色 roundWidth = array.getInt(R.styleable.CustomView_roundWidth, 30);//圆环宽度 array.recycle(); //动画 animator = ValueAnimator.ofFloat(0, progress); animator.setDuration(1800); animator.setInterpolator(new OvershootInterpolator()); animator.addUpdateListener(animation -> { nowPro = (float) animation.getAnimatedValue(); postInvalidate(); }); animator.start(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); if (widthSpecMode == MeasureSpec.AT_MOST) {//可获得最大空间 setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2)); } else if (widthMeasureSpec == MeasureSpec.EXACTLY) {//一般指精确值 setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2)); //setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2))); } else { setMeasuredDimension(widthSpecSize, (viewWidth / 2) + (int) (Math.cos(20) * (viewWidth / 2))); } Log.e(TAG, "onMeasure: "+widthSpecSize+","+widthSpecMode); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); viewWidth = w;//得到宽度以此来计算控件所占实际大小 todo 控件宽度 //todo 刨除padding int realWidth=viewWidth-defaultPadding*2; //todo 计算画布所占区域 //oval = new RectF(100,0,viewWidth/2+100,viewWidth/2); oval = new RectF(defaultPadding*2, -(realWidth/2)+defaultPadding, realWidth, realWidth/2); //oval = new RectF(defaultPadding, (-viewWidth / 2) + defaultPadding, viewWidth-defaultPadding, (viewWidth-defaultPadding) / 2); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setAntiAlias(true); //设置画笔为无锯齿 paint.setStrokeWidth(roundWidth); //线宽 paint.setStrokeCap(Paint.Cap.ROUND); //TODO 绘制未完成进度弧线 paint.setColor(roundColor); //设置未完成弧线颜色 paint.setStyle(Paint.Style.STROKE); canvas.drawArc(oval, 180, -180, false, paint); //绘制圆弧 //TODO 绘制进度弧线 paint.setColor(progressColor); paint.setStrokeWidth(roundWidth); paint.setStyle(Paint.Style.STROKE); canvas.drawArc(oval, 180, -(180 * nowPro / max), false, paint); //绘制圆弧 if (textIsShow) { paint.setColor(textColor); paint.setStrokeWidth(0); paint.setTypeface(Typeface.DEFAULT); paint.setTextSize(textSize * 2); float textWidth = paint.measureText((int) ((nowPro / (float) max) * 100) + "%"); canvas.drawText((int) ((nowPro / (float) max) * 100) + "%", viewWidth / 2 - textWidth / 2, viewWidth / 2, paint); } } private int getDefaultHeight() { return 0; } private int getDefaultWidth() { return 0; } public int getRoundColor() { return roundColor; } public void setRoundColor(int roundColor) { this.roundColor = roundColor; } public int getProgressColor() { return progressColor; } public void setProgressColor(int progressColor) { this.progressColor = progressColor; } public boolean getText() { return textIsShow; } public void setText(boolean text) { this.textIsShow = text; } public float getTextSize() { return textSize; } public void setTextSize(float textSize) { this.textSize = textSize; } public int getTextColor() { return textColor; } public void setTextColor(int textColor) { this.textColor = textColor; } public int getMax() { return max; } public void setMax(int max) { this.max = max; } public int getProgress() { return progress; } public void setProgress(int progress) { this.progress = progress; } } ``` ++问题: 下面控件使用中,设置具体的100dp,或者match_parent后,该控件未正常显示,只显示一个线条,问题出在哪里?++ ``` <com.galen.calculator.common.view.CustomView android:id="@+id/vView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/dp_40" app:roundColor="@android:color/holo_blue_dark" app:roundWidth="45" android:background="@color/color_99" app:textColor="@android:color/black" app:textIsShow="true" app:textSize="14sp" /> ``` 
Android自定义控件继承view,设置具体dp值和match_prarent后,控件不显示的问题
自定义了一个半圆进度条控件,代码如下:
```
package com.galen.calculator.common.view;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import com.galen.calculator.R;
public class CustomView extends View {
private static final String TAG="CustomView";
//画笔
private Paint paint;
private RectF oval;
//圆弧颜色
private int roundColor;
//进度颜色
private int progressColor;
//文字内容
private boolean textIsShow;
//字体大小
private float textSize = 14;
//文字颜色
private int textColor;
//最大进度
private int max = 100;
//当前进度
private int progress = 15;
//圆弧宽度
private int roundWidth = 10;
private int viewWidth; //宽度--控件所占区域
private float nowPro = 0;//用于动画
private int defaultPadding=40;
private ValueAnimator animator;
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs, context,defStyleAttr);
}
private void initAttrs(AttributeSet attr, Context context, int defStyleAttr) {
TypedArray array = context.obtainStyledAttributes(attr, R.styleable.CustomView,defStyleAttr,0);
roundColor = array.getColor(R.styleable.CustomView_roundColor, Color.BLACK);//环形颜色
progressColor = array.getColor(R.styleable.CustomView_progressColor, Color.RED);//进度颜色
textIsShow = array.getBoolean(R.styleable.CustomView_textIsShow, false);//文字
textSize = array.getDimension(R.styleable.CustomView_textSize, 14);//文字大小
textColor = array.getColor(R.styleable.CustomView_textColor, Color.BLACK);//文字颜色
roundWidth = array.getInt(R.styleable.CustomView_roundWidth, 30);//圆环宽度
array.recycle();
//动画
animator = ValueAnimator.ofFloat(0, progress);
animator.setDuration(1800);
animator.setInterpolator(new OvershootInterpolator());
animator.addUpdateListener(animation -> {
nowPro = (float) animation.getAnimatedValue();
postInvalidate();
});
animator.start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST) {//可获得最大空间
setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2));
} else if (widthMeasureSpec == MeasureSpec.EXACTLY) {//一般指精确值
setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2));
//setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2)));
} else {
setMeasuredDimension(widthSpecSize, (viewWidth / 2) + (int) (Math.cos(20) * (viewWidth / 2)));
}
Log.e(TAG, "onMeasure: "+widthSpecSize+","+widthSpecMode);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;//得到宽度以此来计算控件所占实际大小 todo 控件宽度
//todo 刨除padding
int realWidth=viewWidth-defaultPadding*2;
//todo 计算画布所占区域
//oval = new RectF(100,0,viewWidth/2+100,viewWidth/2);
oval = new RectF(defaultPadding*2, -(realWidth/2)+defaultPadding, realWidth, realWidth/2);
//oval = new RectF(defaultPadding, (-viewWidth / 2) + defaultPadding, viewWidth-defaultPadding, (viewWidth-defaultPadding) / 2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true); //设置画笔为无锯齿
paint.setStrokeWidth(roundWidth); //线宽
paint.setStrokeCap(Paint.Cap.ROUND);
//TODO 绘制未完成进度弧线
paint.setColor(roundColor); //设置未完成弧线颜色
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 180, -180, false, paint); //绘制圆弧
//TODO 绘制进度弧线
paint.setColor(progressColor);
paint.setStrokeWidth(roundWidth);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 180, -(180 * nowPro / max), false, paint); //绘制圆弧
if (textIsShow) {
paint.setColor(textColor);
paint.setStrokeWidth(0);
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(textSize * 2);
float textWidth = paint.measureText((int) ((nowPro / (float) max) * 100) + "%");
canvas.drawText((int) ((nowPro / (float) max) * 100) + "%", viewWidth / 2 - textWidth / 2, viewWidth / 2, paint);
}
}
private int getDefaultHeight() {
return 0;
}
private int getDefaultWidth() {
return 0;
}
public int getRoundColor() {
return roundColor;
}
public void setRoundColor(int roundColor) {
this.roundColor = roundColor;
}
public int getProgressColor() {
return progressColor;
}
public void setProgressColor(int progressColor) {
this.progressColor = progressColor;
}
public boolean getText() {
return textIsShow;
}
public void setText(boolean text) {
this.textIsShow = text;
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
}
++问题: 下面控件使用中,设置具体的100dp,或者match_parent后,该控件未正常显示,只显示一个线条,问题出在哪里?++
<com.galen.calculator.common.view.CustomView
android:id="@+id/vView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_40"
app:roundColor="@android:color/holo_blue_dark"
app:roundWidth="45"
android:background="@color/color_99"
app:textColor="@android:color/black"
app:textIsShow="true"
app:textSize="14sp" />

Android自定义控件继承view,设置具体dp值和match_prarent后,控件不显示的问题
自定义了一个半圆进度条控件,代码如下:
```
package com.galen.calculator.common.view;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.OvershootInterpolator;
import com.galen.calculator.R;
public class CustomView extends View {
private static final String TAG="CustomView";
//画笔
private Paint paint;
private RectF oval;
//圆弧颜色
private int roundColor;
//进度颜色
private int progressColor;
//文字内容
private boolean textIsShow;
//字体大小
private float textSize = 14;
//文字颜色
private int textColor;
//最大进度
private int max = 100;
//当前进度
private int progress = 15;
//圆弧宽度
private int roundWidth = 10;
private int viewWidth; //宽度--控件所占区域
private float nowPro = 0;//用于动画
private int defaultPadding=40;
private ValueAnimator animator;
public CustomView(Context context) {
this(context, null);
}
public CustomView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initAttrs(attrs, context,defStyleAttr);
}
private void initAttrs(AttributeSet attr, Context context, int defStyleAttr) {
TypedArray array = context.obtainStyledAttributes(attr, R.styleable.CustomView,defStyleAttr,0);
roundColor = array.getColor(R.styleable.CustomView_roundColor, Color.BLACK);//环形颜色
progressColor = array.getColor(R.styleable.CustomView_progressColor, Color.RED);//进度颜色
textIsShow = array.getBoolean(R.styleable.CustomView_textIsShow, false);//文字
textSize = array.getDimension(R.styleable.CustomView_textSize, 14);//文字大小
textColor = array.getColor(R.styleable.CustomView_textColor, Color.BLACK);//文字颜色
roundWidth = array.getInt(R.styleable.CustomView_roundWidth, 30);//圆环宽度
array.recycle();
//动画
animator = ValueAnimator.ofFloat(0, progress);
animator.setDuration(1800);
animator.setInterpolator(new OvershootInterpolator());
animator.addUpdateListener(animation -> {
nowPro = (float) animation.getAnimatedValue();
postInvalidate();
});
animator.start();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
if (widthSpecMode == MeasureSpec.AT_MOST) {//可获得最大空间
setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2));
} else if (widthMeasureSpec == MeasureSpec.EXACTLY) {//一般指精确值
setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2));
//setMeasuredDimension(widthMeasureSpec, (widthSpecSize / 2) + (int) (Math.cos(20) * (widthSpecSize / 2)));
} else {
setMeasuredDimension(widthSpecSize, (viewWidth / 2) + (int) (Math.cos(20) * (viewWidth / 2)));
}
Log.e(TAG, "onMeasure: "+widthSpecSize+","+widthSpecMode);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;//得到宽度以此来计算控件所占实际大小 todo 控件宽度
//todo 刨除padding
int realWidth=viewWidth-defaultPadding*2;
//todo 计算画布所占区域
//oval = new RectF(100,0,viewWidth/2+100,viewWidth/2);
oval = new RectF(defaultPadding*2, -(realWidth/2)+defaultPadding, realWidth, realWidth/2);
//oval = new RectF(defaultPadding, (-viewWidth / 2) + defaultPadding, viewWidth-defaultPadding, (viewWidth-defaultPadding) / 2);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(true); //设置画笔为无锯齿
paint.setStrokeWidth(roundWidth); //线宽
paint.setStrokeCap(Paint.Cap.ROUND);
//TODO 绘制未完成进度弧线
paint.setColor(roundColor); //设置未完成弧线颜色
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 180, -180, false, paint); //绘制圆弧
//TODO 绘制进度弧线
paint.setColor(progressColor);
paint.setStrokeWidth(roundWidth);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(oval, 180, -(180 * nowPro / max), false, paint); //绘制圆弧
if (textIsShow) {
paint.setColor(textColor);
paint.setStrokeWidth(0);
paint.setTypeface(Typeface.DEFAULT);
paint.setTextSize(textSize * 2);
float textWidth = paint.measureText((int) ((nowPro / (float) max) * 100) + "%");
canvas.drawText((int) ((nowPro / (float) max) * 100) + "%", viewWidth / 2 - textWidth / 2, viewWidth / 2, paint);
}
}
private int getDefaultHeight() {
return 0;
}
private int getDefaultWidth() {
return 0;
}
public int getRoundColor() {
return roundColor;
}
public void setRoundColor(int roundColor) {
this.roundColor = roundColor;
}
public int getProgressColor() {
return progressColor;
}
public void setProgressColor(int progressColor) {
this.progressColor = progressColor;
}
public boolean getText() {
return textIsShow;
}
public void setText(boolean text) {
this.textIsShow = text;
}
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public int getMax() {
return max;
}
public void setMax(int max) {
this.max = max;
}
public int getProgress() {
return progress;
}
public void setProgress(int progress) {
this.progress = progress;
}
}
++问题: 下面控件使用中,设置具体的100dp,或者match_parent后,该控件未正常显示,只显示一个线条,问题出在哪里?++
<com.galen.calculator.common.view.CustomView
android:id="@+id/vView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/dp_40"
app:roundColor="@android:color/holo_blue_dark"
app:roundWidth="45"
android:background="@color/color_99"
app:textColor="@android:color/black"
app:textIsShow="true"
app:textSize="14sp" />

android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
View的宽度是0 ,1、可以改成100dp 或者 2、修改 onMeasure
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
View的宽度是0 ,1、可以改成100dp 或者 2、修改 onMeasure