本文同步自博主的个人博客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. [BZOJ]4162: shlw loves matrix II

    Time Limit: 30 Sec  Memory Limit: 128 MB Description 给定矩阵 M,请计算 M^n,并将其中每一个元素对 1000000007 取模输出. Inpu ...

  2. 基于 HTML5 的 WebGL 3D 智能楼宇监控系统

    前言 智能监控的领域已经涉及到了各大领域,工控.电信.电力.轨道交通.航天航空等等,为了减少人员的消耗,监控系统必不可少.之前我写过一篇 2D 的智能地铁监控系统广受好评,突然觉得,既然 2D 的这么 ...

  3. 提高Mysql查询速度的一些建议(转).

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  4. Python中dict的功能介绍

    Dict的功能介绍 1. 字典的两种函数(方法) 1. 字典的内置函数 包含关系 格式:x.__contains__(key)等同于key in x 例如:dic = {'ab':23,'cd':34 ...

  5. Struts+Hibernate+jsp页面,实现分页

    dao层代码 package com.hanqi.dao; import java.util.ArrayList; import java.util.List; import org.hibernat ...

  6. numpy的初探

    # data = numpy.genfromtxt("C:\\Users\\Admin\Desktop\\111.txt", delimiter='\t', dtype='str' ...

  7. ubuntu14.04 python2.7 安装配置OpenCV3.0

    环境:ubuntu14.04  python2.7 内容:安装并配置OpenCV3.0 今天按照OpenCV官网上的步骤装了OpenCV但是,装好之后python提示“No module named ...

  8. python 常用镜像

    pip镜像https://pypi.tuna.tsinghua.edu.cn/simplehttps://pypi.douban.io.com/simple pip install python-qt ...

  9. MLDS笔记:Optimization

    当函数空间覆盖到目标函数时,如何通过优化调整神经网络的参数找到这个目标函数呢? 深度学习中的损失函数是非凸的,非凸优化是个NP-hard问题,如何通过梯度下降来解决这个问题呢? 注意,不同于learn ...

  10. jQuery 遍历 – 过滤

    缩小搜索元素的范围 三个最基本的过滤方法是:first(), last() 和 eq(),它们允许您基于其在一组元素中的位置来选择一个特定的元素. 其他过滤方法,比如 filter() 和 not() ...