自定义电池充电动画
2017-10-28 10:01
190 查看
最近公司项目涉及到一个电池充电的效果,需要电量从底部上顶部逐渐变多,再变为0。反复循环。在借鉴了别人写的动画后,自己写了如下动画。里面有些代码是写死的,诸君可以自行修改。效果如下:
话不多说,开始贴代码
1、attrs。这是自定义view必须的。
话不多说,开始贴代码
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=< 13327 /span>"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
相关文章推荐
- 自定义view之 电池充电view动画
- android 自定义view+属性动画实现充电进度条
- Android 自定义view和属性动画实现充电进度条效果
- android 自定义view+属性动画实现充电进度条
- 电池充电时扩散页面动画效果相关
- 安卓开发之自定义动画控件BatteryView(电池加载动画)
- 为android 6.0 添加电池充电动画
- QML之自定义电池充电/电量显示效果
- 仿电池电量充电、上下左右剪切动画
- android简单的自定义动画
- [android] 练习样式主题自定义activity切换动画
- 自定义view-视察动画之雅虎新闻摘要加载
- 波浪动画实现方法的改进——用自定义SurfaceView实现
- 自定义导航转场动画以及更多
- css3的自定义动画轮播
- 自定义视图-圆形动画的使用
- 手机卫士学习16-Activity界面切换自定义动画
- Android_自定义view动画按钮
- Android开发 之 属性动画(自定义ValueAnimator的TypeEvaluator)
- [10秒学会] - 自定义专场动画