Android 自定义控件:百分数动态递增,用于progress显示

来源:互联网 发布:2016淘宝怎么了 编辑:程序博客网 时间:2024/06/06 19:01

主要思想是用一个 Handler 不断地向UI主线程发消息,循环调用updateScore() -> invalidate() -> onDraw() 将百分数用画笔画在屏幕上。

使用示例:

1. 在你的main_layout.xml 文件中加入控件

<com.test.mytest.ScoreAnimationView      android:id="@+id/scan_progress"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:layout_marginBottom="5dp"      android:layout_centerInParent="true"      android:text="0%" />
2. 在MainActivity.java 代码中调用代码
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main_layout);        ScoreAnimationView progressScore = (ScoreAnimationView) findViewById(R.id.scan_progress);        progressScore.startScoreRollAnimation(0, 100);    }

3. ScoreAnimationView.java

package com.test.mytest;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.FontMetrics;import android.os.Handler;import android.util.AttributeSet;import android.view.View;/** * 百分数递增动态显示,可以用于progress显示 */public class ScoreAnimationView extends View {    /** 滚动开始的分数 **/    private int mFromScore = 0;    /** 滚动结束的分数 **/    private int mToScore = 0;    /** 是否开始绘制动画 **/    private boolean isDrawing = false;    /** 分数是否向上滚动 **/    private boolean isUp;    /**多添加两个字符,防止在不同字体时显示不全 */    private final String STRING = "100%__";     private int mViewWidth = 0;    private Paint mScorePaint;    private Context mContext;    private final int START_ANIMATION = 0;    /**     * Handler负责     */    private Handler mHandler = new Handler() {        public void handleMessage(android.os.Message msg) {            switch (msg.what) {            case START_ANIMATION:                updateScore();                break;            }        };    };    public ScoreAnimationView(Context context) {        super(context);        mContext = context;        init();    }    public ScoreAnimationView(Context context, AttributeSet attrs) {        super(context, attrs);        mContext = context;        init();    }    /**     * 初始化画笔     */    private void init() {        mScorePaint = new Paint();        mScorePaint.setColor(mContext.getResources().getColor(R.color.white));        mScorePaint.setTextSize(dip2px(mContext, 60));        mScorePaint.setAntiAlias(true);    }    /**     * 循环刷新页面,动态地将百分数从fromScore增长到toScore     * @param fromScore 起始百分数     * @param toScore 增长到的百分数     */    public void startScoreRollAnimation(int fromScore, int toScore) {        if (fromScore > 0) {            mFromScore = fromScore > 100 ? 100 : fromScore;        } else {            mFromScore = 0;        }        if (toScore > 0) {            mToScore = toScore > 100 ? 100 : toScore;        } else {            mToScore = 0;        }        if ((mFromScore - mToScore) != 0) {            isDrawing = true;            if (mFromScore > mToScore) {                isUp = false;            } else {                isUp = true;            }            mHandler.sendEmptyMessage(START_ANIMATION);        } else {            isDrawing = true;            postInvalidate();        }    }        /**     * 最重要的函数,刷新页面,调用canvas.drawText()函数将百分数画在屏幕上     */    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawColor(Color.TRANSPARENT);        int width = mViewWidth > 0 ? mViewWidth : dip2px(mContext, 150);        if (isDrawing) {            if (mFromScore < 10) {                canvas.drawText(String.valueOf(mFromScore) + "%", mViewWidth/3,                        getStringHeight(mScorePaint), mScorePaint);            } else if (mFromScore < 100) {                canvas.drawText(String.valueOf(mFromScore) + "%", mViewWidth/4,                        getStringHeight(mScorePaint), mScorePaint);            } else {                canvas.drawText(String.valueOf(mFromScore) + "%", mViewWidth/6, getStringHeight(mScorePaint),                        mScorePaint);            }        } else {            if (mFromScore < 10) {                canvas.drawText(String.valueOf(mToScore) + "%", mViewWidth/3,                        getStringHeight(mScorePaint), mScorePaint);            } else if (mToScore >= 100) {                canvas.drawText(String.valueOf(mToScore) + "%", mViewWidth/6, getStringHeight(mScorePaint),                        mScorePaint);            } else {                canvas.drawText(String.valueOf(mToScore) + "%", mViewWidth/4,                        getStringHeight(mScorePaint), mScorePaint);            }        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(getStringWidth(mScorePaint, STRING), getStringHeight(mScorePaint) + 20);        mViewWidth = this.getWidth();    }    /**     * 更新百分数,循环刷新页面的关键函数     */    private void updateScore() {        if (isDrawing) {            if (isUp) {                mFromScore++;                if (mFromScore <= mToScore) {                    invalidate();                    mHandler.sendEmptyMessageDelayed(START_ANIMATION, 100);                } else {                    mFromScore = mToScore;                }            } else {                mFromScore--;                if (mFromScore >= mToScore) {                    invalidate();                    mHandler.sendEmptyMessageDelayed(START_ANIMATION, 100);                } else {                    mFromScore = mToScore;                }            }        }    }    public int getToScore() {        return mToScore;    }    public int getFromScore() {        return mFromScore;    }    public void setTextColor(int colorID) {        if (mScorePaint != null) {            mScorePaint.setColor(colorID);        }        invalidate();    }    /**     * 获取字符串宽度     */    private int getStringWidth(Paint paint, String str) {        int strWidth = 0;        if (str != null && str.length() > 0) {            int length = str.length();            float[] widths = new float[length];            paint.getTextWidths(str, widths);            for (int k = 0; k < length; k++) {                strWidth += (int) Math.ceil(widths[k]);            }        }        return strWidth;    }    /**     * 获取字符串高度     */    private int getStringHeight(Paint paint) {        FontMetrics fm = paint.getFontMetrics();        return (int) (Math.ceil(fm.descent - fm.top) / 1.5);    }    /**     * 将dip转化为pixel     */    private static int dip2px(Context context, float dipValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    }}

0 0