自定义控件 《进度条,统计圆环图》从0基础开始,备注详细,还有其他小技巧

自定义控件 《进度条,统计圆环图》从0基础开始,备注详细,还有其他小技巧  (后续会不断的更新优化)

 说明:外环进度条的颜色 、宽度、底色;百分比的字体、大小、颜色;文字的大小、颜色、进度条动态加载的快慢都可以自定义,在代码中设置  或者  布局中配置。

一、自定义控件View(有详细的注释:小白级别也可看懂)

注释1:TypedArray的使用场景之一,就是上述的自定义View,会随着 Activity的每一次Create而Create,因此,需要系统频繁的创建array,对内存和性能是一个不小的开销,如果不使用池模式,每次都让GC来回收,很可能就会造成OutOfMemory。
这就是使用池+单例模式的原因,这也就是为什么官方文档一再的强调:使用完之后一定 recycle,recycle,recycle。

注释2:postIvalidate  刷新界面

 
 


<span style="font-size:12px;">/**
 * 作者:JXF
 * 创建时间:2016/3/31 下午 2:18
 * 描述:团队统计圆环自定义控件
 */
public class RoundProgressBar extends View {
    /**
     * 画笔对象的引用
     */
    private Paint paint;
    /**
     * 当前的进度
     */
    private int progress;
    /**
     * 进度条样式:空心
     */
    public static final int STROKE = 0;
    /**
     * 进度条样式:实心
     */
    public static final int FILL = 1;

    public RoundProgressBar(Context context) {
        this(context, null);
    }

    public RoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint = new Paint();
        //获取自定义属性和默认值
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgressBar);
        roundColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundColor,getResources().getColor(R.color.stat_background_blue2));
        roundProgressColor = mTypedArray.getColor(R.styleable.RoundProgressBar_roundProgressColor, getResources().getColor(R.color.switch_ios7_color));
        textColor = mTypedArray.getColor(R.styleable.RoundProgressBar_textColor, getResources().getColor(R.color.switch_ios7_color));
        textSize = mTypedArray.getDimension(R.styleable.RoundProgressBar_textSize, 15);
        roundWidth1 = mTypedArray.getDimension(R.styleable.RoundProgressBar_roundWidth1, 8);
        max = mTypedArray.getInteger(R.styleable.RoundProgressBar_max, 100);
        textIsDisplayable = mTypedArray.getBoolean(R.styleable.RoundProgressBar_textIsDisplayable, true);
        style = mTypedArray.getInt(R.styleable.RoundProgressBar_style, 0);
        roundText=mTypedArray.getString(R.styleable.RoundProgressBar_roundText);
        roundTextColor=mTypedArray.getColor(R.styleable.RoundProgressBar_roundTextColor, getResources().getColor(R.color.black_dark));
        roundTextSize=mTypedArray.getDimension(R.styleable.RoundProgressBar_roundTextSize, 15);

        /*防止造成OutOfMemory*/
        mTypedArray.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         *画最外层的大圆
         */
        int centre = getWidth() / 2;//获取圆心的x坐标
        int radius = (int) (centre - roundWidth1 / 2);//圆环的半径
        paint.setColor(roundColor);//设置圆环的颜色
        paint.setStyle(Paint.Style.STROKE);//设置空心
        paint.setStrokeWidth(roundWidth1);//设置圆环的宽度
        paint.setAntiAlias(true); //消除锯齿
        canvas.drawCircle(centre, centre, radius, paint);
        /**
         * 画进度百分比
         */
        paint.setStrokeWidth(0);
        paint.setColor(textColor);
        paint.setTextSize(textSize);
        paint.setTypeface(Typeface.DEFAULT_BOLD);//设置字体
        int percent = (int) (((float) progress / (float) max) * 100);  //中间的进度百分比,先转换成float在进行除法运算,不然都为0
        float textWidth = paint.measureText(percent + "%");   //测量字体宽度,我们需要根据字体的宽度设置在圆环中间
        if (textIsDisplayable && percent != 0 && style == STROKE) {
            canvas.drawText(percent + "%", centre - textWidth/ 2, centre + textSize / 2, paint);//画出进度百分比
        }
        /**
         * 画进度百分比下面的文字
         */
        paint.setStrokeWidth(0);
        paint.setColor(roundTextColor);
        paint.setTextSize(roundTextSize);
        if(roundText==null || roundText.equals("")){
            roundText="默认";
        }
        float text1Width = paint.measureText(roundText);
        if(textIsDisplayable && percent != 0 && style == STROKE){
            canvas.drawText(roundText, centre - text1Width / 2, centre + textSize + textSize/2, paint); //画出进度百分比
        }
        /**
         * 画圆弧 ,画圆环的进度
         */

        //设置进度是实心还是空心
        paint.setStrokeWidth(roundWidth1);//设置圆环的宽度
        paint.setColor(roundProgressColor);//设置进度点饿颜色
        RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius);//用于定义的圆弧的形状和大小的界限
        switch (style) {
            case STROKE: {
                paint.setStyle(Paint.Style.STROKE);
                canvas.drawArc(oval, 0, 360 * progress / max, false, paint);  //fase 实心
                break;
            }
            case FILL: {
                paint.setStyle(Paint.Style.FILL_AND_STROKE);
                if (progress != 0)
                    canvas.drawArc(oval, 0, 360 * progress / max, true, paint);  //根据进度画圆弧    空心
                break;
            }
        }
        /**
         * 进度条达到满的时候触发事件
         */
        if (progress == max && null != onLoadFinish) {
            onLoadFinish.onLoadFinished();
        }

    }

    /*synchronized保证在同一时刻最多只有一个线程执行该段代码*/
    public synchronized int getMax() {
        return max;
    }

    /**
     * 设置进度的最大值
     *
     * @param max
     */
    public synchronized void setMax(int max) {
        if (max < 0) {
            throw new IllegalArgumentException("max not less than 0");
        }
        this.max = max;
    }

    /**
     * 获取进度.需要同步
     *
     * @return
     */
    public synchronized int getProgress() {
        return progress;
    }

    /**
     * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
     * 刷新界面调用postInvalidate()能在非UI线程刷新
     *
     * @param progress
     */
    public synchronized void setProgress(int progress) {
        if (progress < 0) {
            throw new IllegalArgumentException("progress not less than 0");
        }
        if (progress > max) {
            progress = max;
        }
        if (progress <= max) {
            this.progress = progress;
            postInvalidate();//刷新界面
            //postInvalidateDelayed();
        }

    }

    /**
     * 一定一个接口
     */
    public interface OnLoadFinishListener {
        public void onLoadFinished();
    }

    /**
     * 初始化接口变量
     */
    OnLoadFinishListener onLoadFinish = null;

    /**
     * 自定义控件的自定义事件
     *
     * @param listener 接口类型
     */
    public void setOnLoadFinishListener(OnLoadFinishListener listener) {
        onLoadFinish = listener;
    }
/*********************************控件属性(开始)************************************/
    /**
     * 圆环的中的文字
     */
    private String roundText;
    /**
     * 圆环的中的文字颜色
     */
    private int roundTextColor;

    /**
     * 圆环的中的文字大小
     */
    private float roundTextSize;

    /**
     * 圆环的颜色
     */
    private int roundColor;
    /**
     * 圆环进度的颜色
     */
    private int roundProgressColor;
    /**
     * 中间进度百分比的字符串的颜色
     */
    private int textColor;
    /**
     * 中间进度百分比的字符串的字体大小
     */
    private float textSize;
    /**
     * 圆环的宽度
     */
    private float roundWidth1;


    /**
     * 最大的进度
     */
    private int max;
    /**
     * 是否显示中间进度
     */
    private boolean textIsDisplayable;
    /**
     * 进度的风格:实心或者空心
     */
    private int style;

    public String getRoundText() {
        return roundText;
    }

    public void setRoundText(String roundText) {
        this.roundText = roundText;
    }
    public int getRoundTextColor() {
        return roundTextColor;
    }

    public void setRoundTextColor(int roundTextColor) {
        this.roundTextColor = roundTextColor;
    }
    public float getRoundTextSize() {
        return roundTextSize;
    }

    public void setRoundTextSize(float roundTextSize) {
        this.roundTextSize = roundTextSize;
    }
    public int getRoundColor() {
        return roundColor;
    }

    public void setRoundColor(int roundColor) {
        this.roundColor = roundColor;
    }

    public int getRoundProgressColor() {
        return roundProgressColor;
    }

    public void setRoundProgressColor(int roundProgressColor) {
        this.roundProgressColor = roundProgressColor;
    }

    public int getTextColor() {

        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
    }

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    public float getRoundWidth1() {
        return roundWidth1;
    }

    public void setRoundWidth1(float roundWidth) {
        this.roundWidth1= roundWidth;
    }
    /*********************************控件属性(结束)************************************/
}</span>
二、xml中使用自定义控件

 <com.grasp.nsuperseller.view.RoundProgressBar
            android:id="@+id/roundProgressStat"
            android:layout_width="170dip"
            android:layout_height="170dip"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            android:background="@drawable/corner_common_yuan"
            app:roundText="完成率"
            app:roundTextSize="18sp"
            app:textSize="28sp" />
二、xml中自定义圆形背景

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="#f5f9f9"/>
    <size android:width="50dp"  android:height="50dp"/>
</shape>
三、attrs中配置自定义控件的属性值

 <!-- 圆角进度条(开始)-->
    <declare-styleable name="RoundProgressBar">
        <attr name="roundColor" format="color"/>
        <attr name="roundProgressColor" format="color"/>
        <attr name="roundWidth1" format="dimension"/>
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
        <attr name="roundText" format="string"/>
        <attr name="roundTextColor" format="color"/>
        <attr name="roundTextSize" format="dimension"/>
        <attr name="max" format="integer"></attr>
        <attr name="textIsDisplayable" format="boolean"></attr>
        <attr name="style">
            <enum name="STROKE" value="0"></enum>
            <enum name="FILL" value="1"></enum>
        </attr>
    </declare-styleable>
    <!-- 圆角进度条(结束)-->
四、在Activity中使用

备注  :100为最大的值,70为当前进度  ,可自己设置

          50为速度,可以自己改变

 public void companyMonthOnclick() {
        progress = 0;
        roundProgressStat.setProgress(0);
        roundProgressStat.setMax(100);
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (progress < 70) {
                    progress ++;

                    roundProgressStat.setProgress(progress);
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();
    }





 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
自定义控件是指开发者根据自己的需求和设计来创建一种新的控件,以便在应用程序中使用。环形进度条是一种常见的自定义控件,它以环形的形式展示进度状态。在Qt中,可以通过以下步骤来创建一个环形进度条自定义控件: 1. 创建一个新的Qt自定义控件类,例如"CustomCircularProgressBar"。这个类应该继承自QWidget或QProgressBar类。QWidget提供了基本的窗口功能,而QProgressBar是一个进度条控件。 2. 在自定义控件类的头文件中,定义私有成员变量来存储进度条的当前值和最大值,并声明一些用于设置和获取这些值的公有方法。 3. 重写自定义控件类的绘事件函数paintEvent(QPaintEvent *event),在这个函数中绘制环形进度条的外观。可以使用Qt的绘工具类QPainter来绘制圆形和弧线,并根据当前值和最大值计算出进度的角度。 4. 实现自定义控件类的公有方法,用于设置和获取进度条的当前值和最大值。在这些方法中,更新私有成员变量的值,并调用update()函数来触发控件的重绘。 5. 在应用程序中使用自定义控件类。在Qt的设计工具中,将自定义控件拖放到主窗口或其他需要显示环形进度条的地方,并调用相应的公有方法来设置进度条的值。 通过以上步骤,就可以创建一个自定义的环形进度条控件。开发者可以根据自己的需求,进一步扩展和定制这个控件,例如添加动画效果、改变颜色和样式等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄毛火烧雪下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值