自定义电池充电动画

来源:互联网 发布:g41 g42编程实例 编辑:程序博客网 时间:2024/04/29 02:05

最近公司项目涉及到一个电池充电的效果,需要电量从底部上顶部逐渐变多,再变为0。反复循环。在借鉴了别人写的动画后,自己写了如下动画。里面有些代码是写死的,诸君可以自行修改。效果如下:


话不多说,开始贴代码

1、attrs。这是自定义view必须的。

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="charging_progress">        <!--item个数-->        <attr name="cgv_item_count" format="integer" />        <!--方向-->        <attr name="cgv_oritation" format="integer" />        <!--动画时长-->        <attr name="cgv_duration" format="integer" />        <!--边界宽度-->        <attr name="cgv_border_width" format="dimension" />        <!--边界颜色-->        <attr name="cgv_border_color" format="color" />        <!--圆角半径-->        <attr name="cgv_border_cornor_radius" format="dimension" />        <!--充电内模块的宽度-->        <attr name="cgv_item_width" format="dimension" />        <!--充电内模块的高度-->        <attr name="cgv_item_height" format="dimension" />        <!--充电内模块的前景色,充电中的颜色-->        <attr name="cgv_item_charging_src" format="color" />        <!--充电内模块的背景色,未充电的颜色-->        <attr name="cgv_item_charging_background" format="color" />        <!--view 的背景-->        <attr name="cgv_background" format="color" />    </declare-styleable>
</resources>
2、在xml进行引用
<com.example.batteryanim.ChargingProgess    android:id="@+id/chargingprigressView"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    app:cgv_item_count="1000"    app:cgv_item_height="0.2dp"    app:cgv_item_width="100dp"    app:cgv_item_charging_src="#00A1BD"    app:cgv_item_charging_background="#000000"    app:cgv_background="#F9F9F9"    app:cgv_border_width="4dp"    app:cgv_border_color="#00A1BD"/>/>
3、最重要的一个就是自定义这个view
package com.example.batteryanim;import android.animation.ValueAnimator;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.util.Log;import android.util.TypedValue;import android.view.View;import android.view.animation.LinearInterpolator;/** * 充电进度绘制,使用属性动画完成。 */public class ChargingProgess extends View {    private Context mContext;    private Paint mPaint;//外部矩形以及内部充电动画画笔    private Paint mPaintTop;//顶部矩形    private static final int VERTICAL = 0;//竖直方向    private int oritation;//view的方向    private float border_width;//边界宽度    private int item_count;//item个数    private float item_width;//item宽度    private float item_height;//item高度    private int item_charging_src;//view内部的进度前景色    private int item_charging_background;//view内部的进度背景色    private int background;//view背景色    private int border_color; //边界颜色    private float border_cornor_radius; //圆角半径    private int duration;//动画时间    private int mWidth;//整个view的宽度    private int mHeight;//整个view的高度    public static final int AC = 2;    private int chargeType = AC;//充电类型,默认为交流    private int progress = 0;    private ValueAnimator animAC;    private int mCurrPro = 0;    private int mTopRectHigh;//顶部进度条的高度    private int mRect = 50;    private int mWidthRate = 20;    public ChargingProgess(Context context) {        this(context, null);    }    public ChargingProgess(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public ChargingProgess(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.mContext = context;        getSettingValue(attrs);        initView(context);    }    /**     * 获取在xml中设置的属性值     *     * @param attrs     */    private void getSettingValue(AttributeSet attrs) {        TypedArray array = mContext.obtainStyledAttributes(attrs, com.example.batteryanim.R.styleable.charging_progress);        oritation = array.getInt(com.example.batteryanim.R.styleable.charging_progress_cgv_oritation, VERTICAL);        border_width = array.getDimension(com.example.batteryanim.R.styleable.charging_progress_cgv_border_width, dp2px(2));        item_height = array.getDimension(com.example.batteryanim.R.styleable.charging_progress_cgv_item_height, dp2px(10));        item_width = array.getDimension(com.example.batteryanim.R.styleable.charging_progress_cgv_item_width, dp2px(20));        item_charging_src = array.getColor(com.example.batteryanim.R.styleable.charging_progress_cgv_item_charging_src, 0xffffea00);        item_charging_background = array.getColor(com.example.batteryanim.R.styleable.charging_progress_cgv_item_charging_background, 0xff544645);        background = array.getColor(com.example.batteryanim.R.styleable.charging_progress_cgv_background, 0xff463938);        border_color = array.getColor(com.example.batteryanim.R.styleable.charging_progress_cgv_border_color, 0xffb49d7c);        border_cornor_radius = array.getDimension(com.example.batteryanim.R.styleable.charging_progress_cgv_border_cornor_radius, dp2px(2));        duration = array.getInt(com.example.batteryanim.R.styleable.charging_progress_cgv_duration, 10 * 1000);        item_count = array.getInt(com.example.batteryanim.R.styleable.charging_progress_cgv_item_count, 100);    }    /**     * 初始化两种画笔     * @param context     */    private void initView(Context context) {        mPaint = new Paint();        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(border_width);        mPaint.setColor((border_color));        mPaintTop = new Paint();        mPaintTop.setStyle(Paint.Style.FILL);        mPaintTop.setStrokeWidth(border_width);        mPaintTop.setColor(border_color);    }    /**     * 当前进度     * @return     */    public int getProgress() {        return progress % 100;    }    /**     * 设置充电进度     * @param progress     */    public void setProgress(int progress) {        this.progress = progress;        invalidate();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //顶部矩形的宽高        int left = mWidth * 3 / 8;        int top = 0;        int right = 5 * mWidth / 8;        int bottom = (int) (item_height *60);        mTopRectHigh = bottom - top;        //顶部的矩形        RectF topRect = new RectF(left, top, right, bottom);        canvas.drawRoundRect(topRect, border_cornor_radius, border_cornor_radius, mPaintTop);        //大矩形。宽高分别是指最大view的宽高        RectF border = new RectF(0 + 5, bottom + 5, mWidth - 5, mHeight - 5);        canvas.drawRoundRect(border, mRect, mRect, mPaint);        drawACAnimaiton(canvas);        //因为每次刷新都要走onDraw方法,所以之前在drawACAnimaiton设置了画笔,现在要还原        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(border_width);        mPaint.setColor((border_color));    }    /**     * 关闭动画     */    public void closeAnimation() {        progress = 0;        invalidate();        if (animAC != null) {            animAC.cancel();        }    }    /**     * 设置交流动画,属性动画     */    public void setACAnimation() {        chargeType = AC;        animAC = ValueAnimator.ofInt(0, 1000);        animAC.setDuration(10000);        animAC.setInterpolator(new LinearInterpolator());        animAC.setRepeatCount(ValueAnimator.INFINITE);        animAC.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                mCurrPro = (Integer) animation.getAnimatedValue();                Log.i("liwei", "mCurrPro:" + mCurrPro);                invalidate();            }        });        animAC.start();    }    /**     * 绘制交流动画的具体走向     * @param canvas     */    private void drawACAnimaiton(Canvas canvas) {        RectF backRect = null;        //设置从30到970是因为顶部一些地方和底部一些距离要留空白        for (int i = 30; i <= mCurrPro && i <= 970; i++) {            //这里的宽并没有严格按照比例来,而是自己看界面随意调的,mWidthRate也就没有什么含义            float left = mWidth / (mWidthRate + 2) + mWidth * 1 / 50;            //将View里面最下面的矩形是分为1000份的            float top = mHeight - i * item_height;            float right = (mWidthRate + 1) * mWidth / (mWidthRate + 2) - mWidth * 1 / 50;            float bottom = top + item_height;            //这是为顶部和底部的动画准备的,顶部和底部的动画样子和中间部分不同            int bottomDis=60;            int topDis=940;            int timeRate=1;            //最底部动画样子            if (i<bottomDis){                //动画呈现线性               int j=bottomDis-i;                //这里的宽度和中间部分不同                 left = mWidth / (mWidthRate + 2) + mWidth * 1 / 50+j*timeRate;                 right = (mWidthRate + 1) * mWidth / (mWidthRate + 2) - mWidth * 1 / 50-j*timeRate;                backRect = new RectF(left, top, right, bottom);                mPaint.setStyle(Paint.Style.FILL);                mPaint.setColor(item_charging_src);                canvas.drawRect(backRect, mPaint);            }else if (i>topDis){                //最顶部动画样子                //这里的宽度和中间部分不同                //动画呈现线性                int j=i-topDis;                left = mWidth / (mWidthRate + 2) + mWidth * 1 / 50+j*timeRate;                right = (mWidthRate + 1) * mWidth / (mWidthRate + 2) - mWidth * 1 / 50-j*timeRate;                backRect = new RectF(left, top, right, bottom);                mPaint.setStyle(Paint.Style.FILL);                mPaint.setColor(item_charging_src);                canvas.drawRect(backRect, mPaint);            }else if (i==200||i==400||i==600||i==800){                //这边的判断是为了中间动画的空白                backRect = new RectF(left, top, right, bottom);                mPaint.setStyle(Paint.Style.FILL);                mPaint.setColor(Color.WHITE);                canvas.drawRect(backRect, mPaint);            } else{                //中间动画                backRect = new RectF(left, top, right, bottom);                mPaint.setStyle(Paint.Style.FILL);                mPaint.setColor(item_charging_src);                canvas.drawRect(backRect, mPaint);            }        }    }    /**     * 测量view的宽和高     * @param widthMeasureSpec     * @param heightMeasureSpec     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //高度等于中间的矩形高度+最顶部的一个小矩形        mHeight = (int) (item_count * item_height + item_height * 60);        Log.i("liwei", "mHeight:" + mHeight);        mWidth = (int) ((mWidthRate + 2) * item_width / mWidthRate);        setMeasuredDimension(mWidth, mHeight);    }    /**     * dp转化为px`     *     * @param dp     * @return     */    protected int dp2px(int dp) {        return (int) TypedValue.applyDimension(                TypedValue.COMPLEX_UNIT_DIP,                dp,                getResources().getDisplayMetrics());    }    /**     * sp转为px     *     * @param sp     * @return     */    protected int sp2px(int sp) {        return (int) TypedValue.applyDimension(                TypedValue.COMPLEX_UNIT_SP,                sp,                getResources().getDisplayMetrics());    }}
项目下载链接在这里,有建议的也可以在评论里告诉我
http://download.csdn.net/download/qq_25330791/10042581
 

原创粉丝点击