-noUser-
icon 1
Android自定义控件
未解决
Android自定义控件继承view,设置具体dp值和match_prarent后,控件不显示的问题
Android
发布于 2023-03-14 19:29
287浏览

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" /> ``` ![1678793285347.png](https://static-club.oss-cn-shanghai.aliyuncs.com/bbs/bbs_1678793316716.png)

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" />
![1678793285347.png](https://static-club.oss-cn-shanghai.aliyuncs.com/bbs/bbs_1678793316716.png)

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" />
![1678793285347.png](https://static-club.oss-cn-shanghai.aliyuncs.com/bbs/bbs_1678793316716.png)
编写答案
回答问题, 请先登录
1条回答
1
生命的宣言
2023-09-18 14:05

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

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

关注
回答
收藏