Android——自定义ProgressBar显示文字(有缺陷)

一、效果

在这里插入图片描述

二、代码

public class PZHelp_ProgressBar extends ProgressBar {

    Paint  paint;
    Rect   rect;
    String string = "请稍等,正在加载......";

    int viewwidth, viewheight;

    public PZHelp_ProgressBar(Context context) {
        super(context);
        initView();
    }

    public PZHelp_ProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public PZHelp_ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    void setText(String string){
        this.string = string;
    }

    void initView() {
        paint = new Paint();
        rect  = new Rect();
        //因为绘制时需要缩放二分之一,所以这里放大一倍使用32
        paint.setTextSize(32);
        paint.setColor(Color.BLACK);
        paint.setAntiAlias(true);
        paint.getTextBounds(string, 0, string.length(), rect);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //计算出最适合的尺寸
        viewwidth = getMeasuredWidth() + rect.width();
        viewheight = Math.max(getMeasuredHeight(), rect.height());

        //保存
        setMeasuredDimension(viewwidth, viewheight);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        //添加背景色
        canvas.drawColor(Color.WHITE);
        //缩放一半,为了在周围留出白边
        canvas.scale(0.5f, 0.5f);
        //让显示的内容居中,注意,这里是先执行了translate后执行了scale
        canvas.translate(getHeight() >> 1, getHeight() >> 1);
        //绘制原本的ProgressBar
        super.onDraw(canvas);
        //绘制文字
        canvas.drawText(string, (getWidth() + getHeight()) >> 1, (getMeasuredHeight() + rect.height()) >> 1, paint);
    }
}

三、总结

  • 最初是因为官方推荐使用 ProgressBar 来代替 ProgressDialog,而 ProgressBar 并没有添加文字的功能,所以才自定义的。
  • ProgressDialog是继承dialog,使用的是window,能够做到隔绝页面的用户操作,而ProgressBar 没有,但如果我也继续写一个window,那为何不直接用ProgressDialog呢?似乎有点鸡肋。
  • 就当练习自定义View了,我还是接着用我 的dialog吧,下面是顺带的ViewGroup代码

四、附

在这里插入图片描述

<com.example.myview_tets.MyViewGroup
    android:id="@+id/myViewGroup"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="请稍等,正在加载......" />
</com.example.myview_tets.MyViewGroup>
public class MyViewGroup extends ViewGroup {

    int viewWidth, viewHeight;

    public MyViewGroup(Context context) {
        super(context);
    }

    public MyViewGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        //让所有子View计算自己的尺寸
        measureChildren(widthMeasureSpec, heightMeasureSpec);

        //获取子View的尺寸
        viewWidth = 0;viewHeight = 0;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            viewWidth = Math.max(viewWidth, child.getMeasuredWidth());
            viewHeight = viewHeight + child.getMeasuredHeight();
        }

        setMeasuredDimension(viewWidth, viewHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childtop = 0;

        //计算子View的布局
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            //获取子View的尺寸
            int childwidth = child.getMeasuredWidth();
            int childheight = child.getMeasuredHeight();
            //为了view水平居中而计算的左边距
            int childleft = (viewWidth - childwidth) / 2;
            child.layout(childleft, childtop, childleft + childwidth, childtop + childheight);
            childtop += childheight;
        }
    }
}

你可能感兴趣的