自定义电池充电动画
来源:互联网 发布: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、最重要的一个就是自定义这个viewpackage 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
阅读全文
1 0
- 自定义电池充电动画
- 自定义view之 电池充电view动画
- 为android 6.0 添加电池充电动画
- 电池医生专业版充电时小点旋转动画
- 电池充电时扩散页面动画效果相关
- QML之自定义电池充电/电量显示效果
- 聚合物电池充电
- 电池充电时间计算
- 电池充电图标处理
- mac 电池不在充电
- 电池充电时间计算
- 获得电池充电状态
- android 电池充电
- USB 电池充电规范
- 超威电池充电
- 电池充电方式
- 电池充电原理
- Mac笔记本电脑电池完全充电
- 大麦网遭集体吐槽!英雄联盟总决赛门票被翻炒27倍 官方回应...
- 中国人将在2049年首登火星? 斗鱼带你探秘明珠号基地
- 信息流预期年收入超10亿美元 或成百度新增长点
- RabbitMQ安装与测试
- HDOJ 2200 Eddy's AC难题
- 自定义电池充电动画
- 掌柜大作战(15):营业执照图片识别,有点尴尬
- ORA-28002的一个细节
- PAT---1009说反话
- pomelo(七) windows 环境安装
- hdu2680 choose the best route
- CCF——节日
- “/”应用程序中的服务器错误。未能加载文件或程序集“XXXXXX”或它的某一个依赖项。试图加载格式不正确的程序。
- HDU