本文同步自博主的个人博客wing的地方酒馆

很久很久以前,撸了一款loadingview(点击这里回顾),当时觉得还不错,现在看看觉得好丑啊!!! 于是想再撸一个,无意间在这里看到一个很不错的效果,于是手痒了,就想动动手,算起来,也有很久没有写过View了。

效果图

哈,可能又是我自我感觉良好,觉得效果还不错,不过没准再过半年我又嫌弃之前的自己了 哈哈哈。

还有呢,如果你看这篇比较吃力,推荐先去看看我之前学view的时候写的一些博客,难度是一点一点增加的。

简单说说自定义view的学习方式

实现思路

看到效果,首先要分析,这里主要是什么组成的。

首先呐,肯定要画两个圆圈,对吧? 不要告诉我你不会画圆。如果不会,请看上面的链接。

private void drawCircle(Canvas canvas, float present) {
canvas.drawCircle(mWidth / 2, mHeight / 2 -mMaxOffset, mMaxRadius, mPaint);
canvas.drawCircle(mWidth / 2, mHeight / 2 + mMaxOffset, mMaxRadius, mPaint);
}

然后想办法让圈圈转起来,怎么转起来呢,肯定是rotate方法了~~这里提供一个角度参数,让他自增,如果到360呢,就让他等于0,然后invalidate(),就可以实现圈圈转动的效果。


canvas.rotate(mDegrees += 3, mWidth / 2, mHeight / 2);
if (mDegrees == 360) {
mDegrees = 0;
}
invalidate();



恩。。已经转起来了。

接下来要想办法让两个小圆在转圈的过程中靠近,再远离,怎么实现呢?注意上面让小圆有间隔的mMaxOffset!我们可以根据旋转的百分比来动态改变这个offset!

所以,要改一下drawCircle()代码

float present = mDegrees / 360;
if (present < 0.5) {
mOffset = mMaxOffset * present;
} else {
mOffset = mMaxOffset * (1 - present);
} private void drawCircle(Canvas canvas) { canvas.drawCircle(mWidth / 2, mHeight / 2 - mOffset, mMaxRadius, mPaint);
canvas.drawCircle(mWidth / 2, mHeight / 2 + mOffset, mMaxRadius, mPaint);
}

现在是这样,恩..已经有点效果了。

那小圈靠近的时候,粘合动画怎么做?还记得qq消息点去除吗?跟那个道理一样!!! 就是画一个贝塞尔的path。坐标计算思路在模仿qq消息去除效果 这里思路是一样的,只不过微调了辅助点坐标。直接上代码:

 if (present <= 0.37 || present >= 0.63) drawPath(canvas, present);

 private void drawPath(Canvas canvas, float present) {
mPath.reset();
mPath.moveTo(mWidth / 2 - mMaxRadius, mHeight / 2 - mOffset);
mPath.lineTo(mWidth / 2 + mMaxRadius, mHeight / 2 - mOffset); float supportOffset = -30; if (present < 0.25) { //两个球相交
supportOffset = 30;
} else if (present >= 0.25 && present < 0.375f) {
Log.e("present", present + "");
supportOffset = -(480 * present - 150f);
} else if (present > 0.625) { //开始缩小 supportOffset = (480 * present - 330f);
if (present > 0.75) { //两个球开始相交
supportOffset = 30;
}
//supportOffset = 30;
} Log.e("wing", supportOffset + ""); mPath.quadTo(mWidth / 2 + supportOffset, mHeight / 2, mWidth / 2 + mMaxRadius,
mHeight / 2 + mOffset);
mPath.lineTo(mWidth / 2 - mMaxRadius, mHeight / 2 + mOffset);
mPath.quadTo(mWidth / 2 - supportOffset, mHeight / 2, mWidth / 2 - mMaxRadius,
mHeight / 2 - mOffset);
mPath.close();
mPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(mPath, mPaint);
}

有一点值得注意的是,辅助点偏移坐标和percent的关系。以 supportOffset = -(480 * present - 150f);作为说明。这个方程式怎么得出出来的呢。 因为我想让百分比从0.25->0.375变化,而辅助点坐标从-30->30变化,所以是一个简单的初中数学中的线性方程。将k和b带入 y = kx +b 即可轻易得出。

之后在根据percent控制path的显隐,即可实现最上效果图的效果。

如果你感兴趣,可以下载源码研究下~~当然,如果觉得赞,点个star是对我最大的支持~

https://github.com/githubwing/LoadingView

(Android自定义View)来来来,一起再撸一个Material风格loadingView。的更多相关文章

  1. Android 自定义View合集

    自定义控件学习 https://github.com/GcsSloop/AndroidNote/tree/master/CustomView 小良自定义控件合集 https://github.com/ ...

  2. Android自定义View 画弧形,文字,并增加动画效果

    一个简单的Android自定义View的demo,画弧形,文字,开启一个多线程更新ui界面,在子线程更新ui是不允许的,但是View提供了方法,让我们来了解下吧. 1.封装一个抽象的View类   B ...

  3. Android 自定义 view(三)—— onDraw 方法理解

    前言: 上一篇已经介绍了用自己定义的属性怎么简单定义一个view<Android 自定义view(二) -- attr 使用>,那么接下来我们继续深究自定义view,下一步将要去简单理解自 ...

  4. Android 自定义View及其在布局文件中的使用示例(三):结合Android 4.4.2_r1源码分析onMeasure过程

    转载请注明出处 http://www.cnblogs.com/crashmaker/p/3549365.html From crash_coder linguowu linguowu0622@gami ...

  5. Android自定义View

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...

  6. Android自定义View之ProgressBar出场记

    关于自定义View,我们前面已经有三篇文章在介绍了,如果筒子们还没阅读,建议先看一下,分别是android自定义View之钟表诞生记.android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检 ...

  7. android自定义View之NotePad出鞘记

    现在我们的手机上基本都会有一个记事本,用起来倒也还算方便,记事本这种东东,如果我想要自己实现,该怎么做呢?今天我们就通过自定义View的方式来自定义一个记事本.OK,废话不多说,先来看看效果图. 整个 ...

  8. android自定义View之仿通讯录侧边栏滑动,实现A-Z字母检索

    我们的手机通讯录一般都有这样的效果,如下图: OK,这种效果大家都见得多了,基本上所有的android手机通讯录都有这样的效果.那我们今天就来看看这个效果该怎么实现. 一.概述 1.页面功能分析 整体 ...

  9. Android自定义View(CustomCalendar-定制日历控件)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/54020386 本文出自:[openXu的博客] 目录: 1分析 2自定义属性 3onMeas ...

随机推荐

  1. POJ 1324(BFS + 状态压缩)

    题意:给你一条蛇,要求一以最少的步数走到1,1 思路: 最开始一直没想到应该怎样保存状态,后来发现别人用二进制保存蛇的状态,即每两个节点之间的方向和头节点,二进制最多14位(感觉状态保存都能扯到二进制 ...

  2. [BZOJ]1014 火星人prefix(JSOI2008)

    一边听省队dalao讲课一边做题真TM刺激. BZOJ的discuss简直就是题面plus.大样例.SuperHINT.dalao题解的结合体. Description 火星人最近研究了一种操作:求一 ...

  3. Python基础学习(第三周)

    集合的操作 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之间的交集,差集,并集等关系 集合的写法 list_1 = set([ ...

  4. C语言程序设计第二次作业——顺序结构

    (一)改错题 1.输出带框文字:在屏幕上输出以下3行信息. 错误信息1: 错误原因:i和d位置错误 改正方法:i和d位置互换 错误信息2: 错误原因:\n后缺了一个" 改正方法:\n后加一个 ...

  5. SpringBoot中跨域问题

    项目中经常会遇到浏览器跨域的问题,解决方式在启动类中配置 @Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigur ...

  6. 原生JS模拟百度搜索关键字与跳转

    <style type="text/css"> *{ margin: 0; padding: 0; } #text{ width: 300px; height: 30p ...

  7. acm几何

    fzu 2231,N个点求构成的平行四边行个数. 题意简重点在优化上 #include <cstdio> #include <iostream> #include <cs ...

  8. Go 语言循环语句

    在不少实际问题中有许多具有规律性的重复操作,因此在程序中就需要重复执行某些语句. 以下为大多编程语言循环程序的流程图: Go 语言提供了以下几种类型循环处理语句: 循环类型 描述 for 循环 重复执 ...

  9. Docker配置 DNS

    Docker 没有为每个容器专门定制镜像,那么怎么自定义配置容器的主机名和 DNS 配置呢? 秘诀就是它利用虚拟文件来挂载到来容器的 3 个相关配置文件. 在容器中使用 mount 命令可以看到挂载信 ...

  10. mybatis映射器配置细则

    前面三篇博客我们已经多次涉及到映射器的使用了,增删查基本上都用过一遍了,但是之前我们只是介绍了基本用法,实际上mybatis中映射器可以配置的地方还是非常多,今天我们就先来看看映射器还有哪些需要配置的 ...