由于项目要求,需要写一个加载动画,正在加载的时候转圈,加载成功后出现笑脸,加载失败后出现哭脸,于是写了个自定义view,现在贴出来

public class FaceView extends View {

private int status = 0;//0 普通 1成功 2失败

public static final int NORMAL = 0;

public static final int SUCCESS = 1;

public static final int FAILED = 2;

/**

* 画笔对象的引用

*/

private Paint paintArc;

private Paint paintRing;//圆环

private Paint paintEye; //眼睛

private Paint paintMouth;//嘴巴

/**

* 圆环的颜色

*/

private int roundColor;

/**

* 圆环进度的颜色

*/

private int roundProgressColor;

/**

* 圆环的宽度

*/

private float roundWidth;

/**

* 最大进度

*/

private int max;

/**

* 当前进度

*/

private int progress = 0;

private boolean finish = false;

private int eyeRadius = 1;

private long maxTimer = 10;

private int mActionHeartbeat = 1 ;

private CountdownTimerListener mListener;

public FaceView(Context context) {

this(context, null);

}

public FaceView(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public FaceView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

paintRing = new Paint();

paintArc = new Paint();

paintEye = new Paint();

paintMouth = new Paint();

TypedArray mTypedArray = context.obtainStyledAttributes(attrs,

com.qeebike.map.R.styleable.FaceView);

//获取自定义属性和默认值

roundColor = mTypedArray.getColor(com.qeebike.map.R.styleable.FaceView_roundColor, Color.RED);

roundProgressColor = mTypedArray.getColor(com.qeebike.map.R.styleable.FaceView_roundProgressColor, Color.GREEN);

roundWidth = mTypedArray.getDimension(com.qeebike.map.R.styleable.FaceView_roundWidth, 5);

max = mTypedArray.getInteger(com.qeebike.map.R.styleable.FaceView_max, 100);

maxTimer = AppBaseConfigManager.getInstance().getmAppBaseConfigInfo().getBaseInfo().getUnlockTimeOut();

mTypedArray.recycle();

}

private void initPaint() {

}

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

/**

* 画最外层的大圆环

*/

int centre = getWidth() / 2; //获取圆心的x坐标

int quarter = getWidth() / 4;

int third = getWidth() / 3;

int radius = (int) (centre - roundWidth / 2); //圆环的半径

paintRing.setColor(roundColor); //设置圆环的颜色

paintRing.setStyle(Paint.Style.STROKE); //设置空心

paintRing.setStrokeWidth(roundWidth); //设置圆环的宽度

paintRing.setAntiAlias(true); //消除锯齿

paintArc.setColor(roundColor); //设置圆环的颜色

paintArc.setStyle(Paint.Style.STROKE); //设置空心

paintArc.setStrokeWidth(roundWidth); //设置圆环的宽度

paintArc.setAntiAlias(true); //消除锯齿

paintArc.setStrokeCap(Paint.Cap.ROUND);

if (status == FAILED) {

paintArc.setColor(roundColor); //设置进度的颜色

} else {

paintArc.setColor(roundProgressColor); //设置进度的颜色

}

if (status == FAILED) {

paintEye.setColor(roundColor);

} else {

paintEye.setColor(roundProgressColor);

}

paintEye.setStyle(Paint.Style.FILL);

paintEye.setAntiAlias(true);

if (status == FAILED) {

paintMouth.setColor(roundColor);

} else {

paintMouth.setColor(roundProgressColor);

}

paintMouth.setStyle(Paint.Style.STROKE); //设置空心

paintMouth.setStrokeWidth(roundWidth/2); //设置圆环的宽度

paintMouth.setAntiAlias(true);

paintMouth.setStrokeCap(Paint.Cap.ROUND);

//设置进度是实心还是空心

RectF oval = new RectF(centre - radius, centre - radius, centre

+ radius, centre + radius); //用于定义的圆弧的形状和大小的界限

RectF ovalMouthSuccess = new RectF((float) (centre - radius * 0.75), (float) (centre - radius * 0.70),

(float) (centre + radius * 0.70), (float) (centre + radius * 0.75));

RectF ovalMouthFailed = new RectF(centre - (int)(radius *0.65), (int)(centre+ radius*0.35),

centre + (int)(radius *0.65), getWidth());

int current = 360 * progress / max;

// int current = 270;

if (status == NORMAL) {

if (current >= 270) {

canvas.drawArc(oval, current - 270, 270, false, paintArc);

} else {

canvas.drawArc(oval, 0, current, false, paintArc); //根据进度画圆弧

}

postDelayed(new Runnable() {

@Override

public void run() {

progress++;

postInvalidate();

}

}, 1);

} else if (status == SUCCESS) {

canvas.drawCircle(centre, centre, radius, paintRing); //画出圆环

canvas.drawArc(oval, 0, 360, false, paintArc);

canvas.drawCircle(quarter, third, eyeRadius, paintEye);

canvas.drawCircle(getWidth() - quarter, third, eyeRadius, paintEye);

canvas.drawArc(ovalMouthSuccess, 0, 10 * eyeRadius, false, paintMouth);

if (!finish) {

postDelayed(new Runnable() {

@Override

public void run() {

eyeRadius++;

if (eyeRadius == 18) {

finish = true;

}

postInvalidate();

}

}, 1);

}

} else if (status == FAILED) {

canvas.drawCircle(centre, centre, radius, paintRing); //画出圆环

canvas.drawArc(oval, 0, 360, false, paintArc);

canvas.drawCircle(quarter, third, eyeRadius, paintEye);

canvas.drawCircle(getWidth() - quarter, third, eyeRadius, paintEye);

canvas.drawArc(ovalMouthFailed, -160, (float) (eyeRadius * 7.777777), false, paintMouth);

if (!finish) {

postDelayed(new Runnable() {

@Override

public void run() {

eyeRadius++;

if (eyeRadius == 18) {

finish = true;

}

postInvalidate();

}

}, 1);

}

}

}

public void setStatus(int status1) {

this.status = status1;

if (status1 == SUCCESS) {

postInvalidate();

} else if (status1 == FAILED) {

paintMouth.setColor(roundColor);

paintArc.setColor(roundColor);

paintEye.setColor(roundColor);

}

}

public void reset() {

maxTimer = AppBaseConfigManager.getInstance().getmAppBaseConfigInfo().getBaseInfo().getUnlockTimeOut();

status = NORMAL;

progress = 1000;

eyeRadius = 1;

postInvalidate();

finish = false;

mHandler.sendEmptyMessage(mActionHeartbeat);

}

/**

* 设置进度的最大值

*

* @param max

*/

public synchronized void setMax(int max) {

if (max < 0) {

throw new IllegalArgumentException("max not less than 0");

}

this.max = max;

}

public void setmListener(CountdownTimerListener mListener) {

this.mListener = mListener;

}

public interface CountdownTimerListener{

//倒计时是否到达

public void onTimeArrive(boolean isArrive);

}

private Handler mHandler = new Handler() {

public void handleMessage(android.os.Message msg) {

if(msg.what == mActionHeartbeat){

maxTimer = maxTimer - 1000;

if (maxTimer > 0) {

mHandler.sendEmptyMessageDelayed(mActionHeartbeat,1000);

}else{

setStatus(FAILED);

if(mListener!=null){

mListener.onTimeArrive(false);

}

}

}

};

};

}

自定义属性

使用

1、XML

android:id="@id/loading_view"

android:layout_width="130dp"

android:layout_height="130dp"

android:layout_gravity="center"

app:roundProgressColor="@color/colorPrimary"

app:roundWidth="8dp"

app:roundColor="@color/text_gray_normal"

/>

2、Java

mFaceView= (FaceView) view.findViewById(R.id.loading_view);

//开始动画

mFaceView.reset();

//加载成功

mFaceView.setStatus(FaceView.SUCCESS);

//加载失败

mFaceView.setStatus(FaceView.FAILED);

效果展示(静图展示三种状态的样式,实则是动态动画)

91CA375B-BC75-4DDE-B00C-33636AC94DE5.png

AEEADCC4-C65E-49D2-AC8E-21EE27B0F9DB.png

FA5F30C4-0DDB-434E-8B6F-D857C2698A51.png

android自定义笑脸,Android 加载笑脸/哭脸动画相关推荐

  1. android dialog 自定义布局,Android自定义Dialog实现加载对话框效果

    前言 最近开发中用到许多对话框,之前都是在外面的代码中创建AlertDialog并设置自定义布局实现常见的对话框,诸如更新提示等含有取消和删除两个按钮的对话框我们可以通过代码创建一个AlertDial ...

  2. android自定义Glide图片加载(以更改Glide缓存路径和使用ARGB_8888的图片格式为例)

    首先引入Glide: compile 'jp.wasabeef:glide-transformations:2.0.1' 自定义GlideModule package tsou.cn.glidetes ...

  3. Android 自定义本地图片加载库,仿微信相册

    总结一下微信的本地图片加载有以下几个特点,也是提高用户体验的关键点 1.缩略图挨个加载,一个一个加载完毕,直到屏幕所有缩略图都加载完成 2.不等当前屏的所有缩略图加载完,迅速向下滑,滑动停止时立即加载 ...

  4. android自定义笑脸,Android实现笑脸进度加载动画

    最近看到豆瓣的笑脸loading很有意思,看一张效果图: 下面分析一下如何实现这样的效果: 1.默认状态是一张笑脸的状态(一个嘴巴,两个眼睛,默认状态) 2.开始旋转,嘴巴追上眼睛(合并状态) 3.追 ...

  5. android 自定义progressdialog,android自定义ProgressDialog加载效果

    用来记录自己所用到的知识 前两天在做项目的时候发现有时候在访问网络数据的时候由于后台要做的工作较多,给我们返回数据的时间较长,所以老大叫我加了一个加载中的logo图用来提高用户体验. 于是就在网上找了 ...

  6. android圆形点击效果,Android 三种方式实现自定义圆形页面加载中效果的进度条

    [实例简介] Android 三种方式实现自定义圆形页面加载中效果的进度条 [实例截图] [核心代码] ad376a86-a9aa-49bc-8cea-321bcff2c0c3 └── AnimRou ...

  7. android动态设置错误页面,Android中替换WebView加载网页失败时的页面

    我们用webView去请求一个网页链接的时候,如果请求网页失败或无网络的情况下,它会返回给我们这样一个页面,如下图所示: 上面这个页面就是系统自带的页面,你觉得是不是很丑?反正小编本人觉得非常丑,很难 ...

  8. osgi框架 android,基于OSGi的Android应用模块动态加载框架设计与实现

    摘要: 伴随着移动互联网科技水平向4G的飞跃,移动终端的使用日趋常态化,移动智能设备的普及率越来越高,得到了大量使用者的追捧.与此同时,各手机操作系统下应用商店里正充斥着琳琅满目的移动应用产品,用户对 ...

  9. Android仿抖音加载框之两颗小球转动控件

    Android仿抖音加载框之两颗小球转动控件 本篇文章已授权微信公众号 hongyangAndroid(鸿洋)独家发布. 效果图 安卓版抖音v2.5加载框: 本控件效果图: 使用方法 源码地址:And ...

最新文章

  1. Java内存模型与线程
  2. springData jpa update delete
  3. Spring Boot 使用 Graylog 收集日志
  4. VirtualBox全屏切换
  5. python解析不完全的html_【已解决】Scrapy的Python中如何解析部分的html字符串并格式化为html网页源码...
  6. 关于0bug商用之道的第三章的少用模板
  7. mysql找不到sys_解决方法:①MySQL 闪退 ②服务列表里找不到MySQL ③MySQL服务无法启动...
  8. 【BZOJ】1497: [NOI2006]最大获利 最大权闭合子图或最小割
  9. mysql 查询简单记忆_mysql 函数大全-简单的总结,便于记忆
  10. 电脑联网了但是浏览器代理服务器出现了问题
  11. java编译程序包不存在_在cmd下编译Java源文件文件出现程序包xxxx不存在
  12. 苹果公司发展史_苹果公司的发展历史
  13. 计算机内存条如何区分频率,Win7怎么看内存条频率,教您查看方法
  14. Mac系统control,option,command的区别
  15. APP指的是智能手机的第三方应用
  16. 一天1个机器学习知识点(一)
  17. android charles 证书_手机安装Charles证书
  18. 添加solidworks许可证服务器,SolidWorks许可服务器问题排查
  19. php 文字 url编码,如何实现php中文转url编码
  20. Mac 开发 打开系统偏好设置

热门文章

  1. BT被封,照样看美剧!
  2. WatchGuard 防火墙封 BT
  3. asp.net907-图形文件管理系统的设计与开发#毕业设计
  4. ORA-00918: column ambiguously defined错误应对方法
  5. Mouse Stroke——Chrome鼠标手势扩展
  6. 怎么关闭计算机硬件加速,如何关闭硬件加速
  7. win7桌面图标不可读文件样式的东西遮挡
  8. mysql查询中,数据按拼音字母排序
  9. 罗永浩仍未放弃收购苹果!
  10. 总有一种幸福会走过来