自定义view——水平进度条

这里写图片描述
做之前需要了解一些知识

  • 文字宽高获取:一般有以下几种方式
    ①:设置文字矩形,Paint.getTextBounds方法得到宽高
String test = "Android世界";
Rect rect = new Rect();
mPaint.getTextBounds(text, 0, test.length(), rect);
int width = rect.width();//文字宽
int height = rect.height();//文字高

②获取文字的宽高
首先宽:

        String text = getProgress() + "%";
        int textWidth = (int) mPaint.measureText(text);

然后高

结论:

           //文字的高:
            int textHeight = (int) (mPaint.descent() - mPaint.ascent());

分析(参考文章:http://blog.csdn.net/u012551350/article/details/51361778):
这里写图片描述

ascent = ascent线的y坐标 - baseline线的y坐标;//负数

descent = descent线的y坐标 - baseline线的y坐标;//正数

top = top线的y坐标 - baseline线的y坐标;//负数

bottom = bottom线的y坐标 - baseline线的y坐标;//正数

leading = top线的y坐标 - ascent线的y坐标;//负数

文字的高应该等于asecnt+descent,但是ascent是负的所以mPaint.descent() - mPaint.ascent()

自定义view

package com.yijia.myapplication;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

/**
 * 项目名:AndFix
 * 包名:com.yijia.myapplication
 * 文件名:HorizontalProgrssBarWithProgess
 * 创建者:周成东
 * 创建时间:2018/1/29 19:44
 * 描述:ToDo
 */

public class HorizontalProgrssBarWithProgess extends ProgressBar {
    private static final int DEFAULT_TEXT_SIZE = 10;//sp
    private static final int DEFAULT_TEXT_COLOR = 0XFFC00D1;
    private static final int DEFAULT_COLOR_UNREACH = 0XFFD3D6DA;
    private static final int DEFAULT_HEIGHT_UNREACH = 2;//dp
    private static final int DEFAULT_COLOR_REACH = DEFAULT_TEXT_COLOR;
    private static final int DEFAULT_HEIGHT_REACH = 2;//dp
    private static final int DEFAULT_TEXT_OFFSET = 10;//dp

    private int mTextSize = s2px(DEFAULT_TEXT_SIZE);
    private int mTextColor = DEFAULT_TEXT_COLOR;
    private int mUnReachColor = DEFAULT_COLOR_UNREACH;
    private int mUnReachHeight = d2px(DEFAULT_HEIGHT_UNREACH);
    private int mReachColor = DEFAULT_COLOR_REACH;
    private int mReachHeight = d2px(DEFAULT_HEIGHT_REACH);
    private int mTextOffset = d2px(DEFAULT_TEXT_OFFSET);

    private Paint mPaint;

    private int mRealWidth;

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

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

    public HorizontalProgrssBarWithProgess(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        obtainStyledAttrs(attrs);
        mPaint = new Paint();
        mPaint.setTextSize(mTextSize);
    }

    private void obtainStyledAttrs(AttributeSet attrs) {
        TypedArray ta = getContext().obtainStyledAttributes(attrs,
                R.styleable.HorizontalProgrssBarWithProgess);
        mTextSize = (int) ta.getDimension(R.styleable.HorizontalProgrssBarWithProgess_progress_text_size,
                mTextSize);
        mTextColor = ta.getColor(R.styleable.HorizontalProgrssBarWithProgess_progress_text_color,
                mTextColor);
        mUnReachColor = ta.getColor(R.styleable.HorizontalProgrssBarWithProgess_progress_unreach_color
                , mUnReachColor);
        mUnReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgrssBarWithProgess_progress_unreach_height
                , mUnReachHeight);
        mReachColor = ta.getColor(R.styleable.HorizontalProgrssBarWithProgess_progress_reach_color
                , mReachColor);
        mReachHeight = (int) ta.getDimension(R.styleable.HorizontalProgrssBarWithProgess_progress_reach_height
                , mReachHeight);
        mTextOffset = (int) ta.getDimension(R.styleable.HorizontalProgrssBarWithProgess_progress_text_offset,
                mTextOffset);
        //一定不要忘了回收
        ta.recycle();


    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //int widhtMode = MeasureSpec.getMode(widthMeasureSpec);
        int widhtSize = MeasureSpec.getSize(widthMeasureSpec);

        int height = measureHeight(heightMeasureSpec);
        setMeasuredDimension(widhtSize, height);
        mRealWidth = widhtSize - getPaddingRight() - getPaddingLeft();
    }

    private int measureHeight(int heightMeasureSpec) {
        int result;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            //文字的高
            int textHeight = (int) (mPaint.descent() - mPaint.ascent());
            result = getBottom() + getTop() + Math.max(Math.max(mUnReachHeight, mReachHeight),
                    Math.abs(textHeight));
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }

        }
        return result;
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(getLeft(), getHeight() / 2);

        boolean noNeedUnRech = false;
        float radio = getProgress() * 1.0f / getMax();
        float progressX = radio * getWidth();


        String text = getProgress() + "%";
        int textWidth = (int) mPaint.measureText(text);
        if (textWidth + progressX > mRealWidth) {
            progressX = mRealWidth - textWidth;
            noNeedUnRech = true;
        }
        float endX = progressX - mTextOffset / 2;
        if (endX > 0) {
            mPaint.setColor(mReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0, 0, endX, 0, mPaint);
        }

        //drawText
        mPaint.setColor(mTextColor);
        int y = (int) (-(mPaint.ascent() + mPaint.descent()) / 2);
        canvas.drawText(text, progressX, y, mPaint);

        //mUnReach bar
        if (!noNeedUnRech) {
            float startX = progressX + mTextOffset / 2 + textWidth;
            mPaint.setColor(mUnReachColor);
            mPaint.setStrokeWidth(mUnReachHeight);
            canvas.drawLine(startX,0,mRealWidth,0,mPaint);
        }
        canvas.restore();
    }

    private int d2px(int dpValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpValue
                , getResources().getDisplayMetrics());
    }

    private int s2px(int spValue) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spValue
                , getResources().getDisplayMetrics());
    }
}

自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="progress_unreach_color" format="color"/>
    <attr name="progress_unreach_height" format="dimension"/>
    <attr name="progress_reach_color" format="color"/>
    <attr name="progress_reach_height" format="dimension"/>
    <attr name="progress_text_color" format="color"/>
    <attr name="progress_text_size" format="dimension"/>
    <attr name="progress_text_offset" format="dimension"/>
    <declare-styleable name="HorizontalProgrssBarWithProgess">
        <attr name="progress_unreach_color"/>
        <attr name="progress_unreach_height" />
        <attr name="progress_reach_color" />
        <attr name="progress_reach_height" />
        <attr name="progress_text_color"/>
        <attr name="progress_text_size" />
        <attr name="progress_text_offset" />
    </declare-styleable>
</resources>

MainActivity

public class MainActivity extends Activity {
    private static final int MSG = 0;
    HorizontalProgrssBarWithProgess mProgess;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int progress = mProgess.getProgress();
            mProgess.setProgress(++progress);
            if (progress >= 100) {
                handler.removeMessages(MSG);
            }
            handler.sendEmptyMessage(MSG);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mProgess = (HorizontalProgrssBarWithProgess) findViewById(R.id.progress);
        handler.sendEmptyMessage(MSG);

    }


}

布局

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    xmlns:yj="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
>

    <com.yijia.myapplication.HorizontalProgrssBarWithProgess
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:progress="50"
         android:padding="5dp"
        android:layout_marginTop="30dp"
        />

    <com.yijia.myapplication.HorizontalProgrssBarWithProgess
        android:id="@+id/progress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:progress="50"
         android:padding="5dp"
        android:layout_marginTop="30dp"
        yj:progress_text_color="#44ff0000"
        yj:progress_unreach_color="#f000"
        yj:progress_reach_color="@color/colorAccent"
        />

</LinearLayout>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值