自定义多节点进度条

来源:互联网 发布:旅行用翻译软件 编辑:程序博客网 时间:2024/06/03 07:32
package cn.mallupdate.android.util;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Point;import android.graphics.Rect;import android.graphics.Typeface;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.View;import com.logistics.android.R;import java.util.ArrayList;/** * 多节点进度条自定义视图 * * @author huqiang */public class MutiProgress extends View {    private int nodesNum; //节点数量    private Drawable progressingDrawable;  //进行中的图标    private Drawable unprogressingDrawable;    private Drawable progresFailDrawable;  //失败的节点    private Drawable progresSuccDrawable;  //成功的节点    private int nodeRadius;  //节点的半径    private int processingLineColor;  //进度条的颜色    // private int progressLineHeight;   //进度条的高度    private int currNodeNO;  //当前进行到的节点编号。从0开始计算    private int currNodeState; //当前进行到的节点编号所对应的状态 0:失败  1:成功    private int textSize;  //字体大小    Context mContext;    int mWidth, mHeight;    private Paint mPaint;    private Canvas mCanvas;    private Bitmap mBitmap; //mCanvas绘制在这上面    private ArrayList<Node> nodes;    private int reward1, reward2, reward3, reward4;    private float endWidth;    private float mPressent = 0;    private int DEFAULT_LINE_COLOR = Color.BLUE;    public MutiProgress(Context context) {        this(context, null);    }    public MutiProgress(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public MutiProgress(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        mContext = context;        textSize = sp2px(context, 11);        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.MutiProgress);        nodesNum = mTypedArray.getInteger(R.styleable.MutiProgress_nodesNum, 1); //节点数量,默认一个节点        nodeRadius = mTypedArray.getDimensionPixelSize(R.styleable.MutiProgress_nodeRadius, 10); //节点半径        progressingDrawable = mTypedArray.getDrawable(R.styleable.MutiProgress_progressingDrawable);        unprogressingDrawable = mTypedArray.getDrawable(R.styleable.MutiProgress_unprogressingDrawable);        progresFailDrawable = mTypedArray.getDrawable(R.styleable.MutiProgress_progresFailDrawable);        progresSuccDrawable = mTypedArray.getDrawable(R.styleable.MutiProgress_progresSuccDrawable);        processingLineColor = mTypedArray.getColor(R.styleable.MutiProgress_processingLineColor, DEFAULT_LINE_COLOR);        currNodeState = mTypedArray.getInt(R.styleable.MutiProgress_currNodeState, 1);        currNodeNO = mTypedArray.getInt(R.styleable.MutiProgress_currNodeNO, 1);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        mWidth = getMeasuredWidth();        mHeight = getMeasuredHeight();        mBitmap = Bitmap.createBitmap(mWidth, mHeight, Config.ARGB_8888);        mPaint = new Paint();        mPaint.setColor(processingLineColor);        mPaint.setAntiAlias(true);//        mPaint.setStrokeJoin(Paint.Join.ROUND); // 圆角//        mPaint.setStrokeCap(Paint.Cap.ROUND); // 圆角        mCanvas = new Canvas(mBitmap);        nodes = new ArrayList<Node>();        float nodeWidth = ((float) (mWidth - nodeRadius * nodesNum * 2)) / (nodesNum - 1);        for (int i = 0; i < nodesNum; i++) {            Node node = new Node();            if (i == 0) {                node.mPoint = new Point(((int) nodeWidth * i), mHeight / 2 - nodeRadius);            } else {                node.mPoint = new Point(((int) nodeWidth * i) + (nodeRadius * 2 * i), mHeight / 2 - nodeRadius);            }            if (currNodeNO == i)                node.type = 1;  //当前进度所到达的节点            else                node.type = 0; //已完成            nodes.add(node);        }    }    class Node {        Point mPoint;        int type; //0:已完成  1:当前到达的进度节点    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);//    DrawProgerss();        //先画背景        Paint bgPaint = new Paint();        bgPaint.setColor(Color.parseColor("#f0f0f0"));        bgPaint.setColor(Color.WHITE);        Rect targetRect = new Rect(0, 0, mWidth, mHeight);        canvas.drawRect(targetRect, bgPaint);        //先画线段,线段的高度为nodeRadius/2        mPaint.setStrokeWidth(nodeRadius / 3 * 2);        //前半截线段//    mCanvas.drawLine(nodeRadius, mHeight/2, mWidth-nodeRadius, mHeight/2, mPaint);  //线段2端去掉nodeRadius        if (currNodeNO + 1 < nodesNum) {            if (mPressent == 0) endWidth = 0;            else                endWidth = (nodes.get(currNodeNO + 1).mPoint.x - nodes.get(currNodeNO).mPoint.x - nodeRadius * 2) * mPressent + nodeRadius * 2 + nodes.get(currNodeNO).mPoint.x;            //前半截线段//    mCanvas.drawLine(nodeRadius, mHeight/2, mWidth-nodeRadius, mHeight/2, mPaint);  //线段2端去掉nodeRadius            mCanvas.drawLine(nodeRadius, mHeight / 2,                    endWidth,                    nodes.get(currNodeNO + 1).mPoint.y + nodeRadius, mPaint);  //线段2端去掉nodeRadius            //后半截线段            mPaint.setColor(Color.parseColor("#dddddd"));            mCanvas.drawLine(endWidth, nodes.get(currNodeNO + 1).mPoint.y + nodeRadius,                    mWidth, mHeight / 2, mPaint);  //线段2端去掉nodeRadius        } else {            mCanvas.drawLine(nodeRadius, mHeight / 2, nodes.get(currNodeNO).mPoint.x + nodeRadius, nodes.get(currNodeNO).mPoint.y + nodeRadius, mPaint);  //线段2端去掉nodeRadius        }//        Log.v("ondraw", "mBitmap=" + mBitmap);        if (mBitmap != null) {            canvas.drawBitmap(mBitmap, new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()), new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()), mPaint);        }        for (int i = 0; i < nodes.size(); i++) {            Node node = nodes.get(i);//            Log.v("ondraw", node.mPoint.x + ";y=" + node.mPoint.y);            if (i < currNodeNO)  //已完成的进度节点            {                progressingDrawable.setBounds(node.mPoint.x, node.mPoint.y, node.mPoint.x + nodeRadius * 2, node.mPoint.y + nodeRadius * 2);                progressingDrawable.draw(canvas);            } else if (i == currNodeNO) {//当前所到达的进度节点(终点)                if (currNodeState == 1) {//判断是成功还是失败  0 :失败  1:成功                    progresSuccDrawable.setBounds(node.mPoint.x, node.mPoint.y, node.mPoint.x + nodeRadius * 2, node.mPoint.y + nodeRadius * 2);                    progresSuccDrawable.draw(canvas);                } else {                    progresFailDrawable.setBounds(node.mPoint.x, node.mPoint.y, node.mPoint.x + nodeRadius * 2, node.mPoint.y + nodeRadius * 2);                    progresFailDrawable.draw(canvas);                }            } else   //未完成的进度节点            {                unprogressingDrawable.setBounds(node.mPoint.x, node.mPoint.y, node.mPoint.x + nodeRadius * 2, node.mPoint.y + nodeRadius * 2);                unprogressingDrawable.draw(canvas);            }        }        bgPaint.setColor(Color.parseColor("#262626"));        bgPaint.setTextSize(textSize);        bgPaint.setFilterBitmap(true);        bgPaint.setTypeface(Typeface.DEFAULT);        Paint.FontMetricsInt fontMetrics = bgPaint.getFontMetricsInt();        int baseline = (targetRect.bottom + targetRect.top - fontMetrics.bottom - fontMetrics.top) / 2;        // 下面这行是实现水平居中,drawText对应改为传入targetRect.centerX()        bgPaint.setTextAlign(Paint.Align.CENTER);        canvas.drawText("¥0", nodeRadius, baseline, bgPaint);        canvas.drawText("¥" + reward1, nodes.get(1).mPoint.x + nodeRadius, baseline, bgPaint);        canvas.drawText("¥" + reward2, nodes.get(2).mPoint.x + nodeRadius, baseline, bgPaint);        canvas.drawText("¥" + reward3, nodes.get(3).mPoint.x + nodeRadius, baseline, bgPaint);        canvas.drawText("¥" + reward4, nodes.get(4).mPoint.x + nodeRadius, baseline, bgPaint);    }    /**     * 将sp值转换为px值,保证文字大小不变     *     * @param spValue     * @param context (DisplayMetrics类中属性scaledDensity)     * @return     */    public static int sp2px(Context context, float spValue) {        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;        return (int) (spValue * fontScale + 0.5f);    }    /**     * 每个节点的值     * @param reward1     * @param reward2     * @param reward3     * @param reward4     */    public void setText(int reward1, int reward2, int reward3, int reward4) {        this.reward1 = reward1;        this.reward2 = reward2;        this.reward3 = reward3;        this.reward4 = reward4;    }    /**     * @param currNodeNO 点亮第N个节点     * @param mPressent 当前节点的百分比     */    public void setCurrNodeNO(int currNodeNO, float mPressent) {        this.mPressent = mPressent;        if (currNodeNO == 0) {            this.currNodeNO = 0;        } else this.currNodeNO = currNodeNO - 1;        invalidate();    }}
 
原创粉丝点击