android模仿支付宝生活圈下拉加载控件TriangleLoadingView
来源:互联网 发布:云计算服务的应用例子 编辑:程序博客网 时间:2024/04/28 15:32
前言
之前看到支付宝做的loading的效果感觉很棒的UI设计,于是就来模仿一个,模仿的效果一般。
支付宝的loading的效果朋友们可以自己看看,这里就不放出来了,下面是loading的模样
正题
先上一张模仿之后的效果图
现在开始我的模仿的一个想法和,首先是要对于这个形状进行模仿,由于是一个六边形,其中包含六个三角形
对于三角形的绘制,由于三角形里面还有一层扇形,同时三角形属于圆角三角形,所以必须注意各个点的绘制。弧形绘制的时候采用的赛贝尔曲线绘制的,渐变利用linearGradient,主要的方法是利用path进行路径绘制,图形如下:
初始化顶点主要方法是在TriangleLoadingView.java里面的方法中进行的,只要确定了六个顶点,那么其余的点都好计算。
protected void initTopPoints(int x, int y) { topPoints = new int[TRIANGLE_NUM][2]; topPoints[0][0] = x - DISTANCE / 2; topPoints[0][1] = y; topPoints[1][0] = (int) (topPoints[0][0] - LENGTH * SIN60) - DISTANCE; topPoints[1][1] = topPoints[0][1] + LENGTH / 2 + DISTANCE; topPoints[2][0] = topPoints[1][0] + DISTANCE; topPoints[2][1] = topPoints[1][1] + LENGTH + DISTANCE; topPoints[3][0] = topPoints[0][0] + DISTANCE + DISTANCE / 2; topPoints[3][1] = topPoints[0][1] + LENGTH * 2 + DISTANCE * 2; topPoints[4][0] = (int) (topPoints[2][0] + 2 * LENGTH * SIN60) + 2 * DISTANCE; topPoints[4][1] = topPoints[2][1] - DISTANCE; topPoints[5][0] = (int) (topPoints[1][0] + 2 * LENGTH * SIN60) + 2 * DISTANCE + DISTANCE / 2; topPoints[5][1] = topPoints[1][1] - DISTANCE; }
在Triangle.java里面实现了绘制三角形的方法,主要计算四个点(三个顶点加一个扇形的角点)由于考虑到不能不断的计算移动或旋转时候的位置点,所以,采用的解决方法是,在六个主要顶点绘制相同大小方向角度的三角形,然后通过canvas.rotate的方式来进行绘制,这样绘制的效果更佳。主要方法是drawSelf()这个方法
public class Triangle{ public final static float TAN30 = 0.5773f; public final static int SHIFT = -TriangleLoadingView.HEIGHT_DEFAULT; private int dev = SHIFT; private int ax; private int ay; private int bx; private int by; private int cx; private int cy; private int dx; private int dy; private int bgColor, topColor; private Path path; private int length = 40; private int rotateDegree; private int rate = 3; private LinearGradient linearGradient; public Triangle(int bx, int by, int rotateDegree, int topColor, int bgColor) { this.length = TriangleLoadingView.LENGTH; this.rate = 3 * length / 40; this.ax = bx - length; this.ay = by; this.bx = bx; this.by = by; this.cx = bx; this.cy = (int) (by + length * TAN30); this.dx = bx - (cy - by); this.dy = (int) (by + (cy - by) * TAN30); this.bgColor = bgColor; this.topColor = topColor; this.rotateDegree = rotateDegree; path = new Path(); linearGradient = new LinearGradient(bx, by, dx, dy, topColor, bgColor, Shader.TileMode.CLAMP); } public void drawSelf(Canvas canvas, Paint paint){ paint.setColor(bgColor); path.moveTo(ax + rate, ay); path.lineTo(bx - rate, by); path.quadTo(bx, by, cx, by + rate); path.lineTo(cx, cy - rate); path.quadTo(cx, cy, cx - rate, cy - rate * TAN30); path.quadTo(ax, ay, ax + rate, ay); path.close(); canvas.save(); canvas.translate(0, dev); canvas.rotate(rotateDegree, bx, by); canvas.drawPath(path, paint); path.reset(); path.moveTo(cx, cy - rate); path.lineTo(cx, by + rate / 2); path.quadTo(cx - length * TAN30 * TAN30, by, cx - length * TAN30 * TriangleLoadingView.SIN60, cy - length * TAN30 * 0.5f); path.lineTo(cx - rate, cy - rate * TAN30); path.quadTo(cx, cy, cx, cy - rate); path.close(); paint.setShader(linearGradient); paint.setColor(Color.GRAY); canvas.drawPath(path, paint); canvas.restore(); paint.setShader(null); } public void moveVertically(int des){ dev = des; } public void moveUp(){ dev -= 3; }}完成了图形的模样之后,接着是三角形的移动,移动主要是根据你的滑动距离来进行的,在Triangle绘制的时候让Canvas.translate()一个偏移量,这样就可以达到一个移动的效果,同时又不用改变三角形的所有点的坐标。接着就是一些边缘的判断和一些特殊情况的处理。
在这个项目进行当中遇到的一个问题就对于一个View的一个default大小应该怎么设置的问题,如果对于View的初始化有一定的了解,那么相信这个问题应该是不难解决的,主要的方法在于重写onMeasure()这个方法,然后使得View具有默认的大小。
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); int width = measureDimension(WIDTH_DEFAULT, widthMeasureSpec); int height = measureDimension(HEIGHT_DEFAULT, heightMeasureSpec); setMeasuredDimension(width, height); } public int measureDimension(int defaultSize, int measureSpec) { int result; int specMode = MeasureSpec.getMode(measureSpec); int specSize = MeasureSpec.getSize(measureSpec); if (specMode == MeasureSpec.EXACTLY) { result = specSize; } else { result = defaultSize; //UNSPECIFIED if (specMode == MeasureSpec.AT_MOST) { result = Math.min(result, specSize); } } return result; }
如果对于这个项目有兴趣,也想了解下里面的实现的话,可以下载下源码,源码在github上
1 0
- android模仿支付宝生活圈下拉加载控件TriangleLoadingView
- Android 自定义View 模仿豆瓣App加载中Loading(也类似支付宝AppLoading)
- android 模仿知乎下拉刷新和上拉加载
- 支付宝iOS版9.2上架:适配iPhone 6s、生活圈、阅后即焚
- 支付宝账单分类+下拉刷新+加载更多
- 安卓/Android 模仿支付宝/微信 支付密码输入框的自定义View
- 模仿 Android支付宝咻一咻功能实现
- Android下拉刷新上拉加载更多ListView控件
- 《android》下拉刷新上拉加载更多控件 PullToRefreshView
- Android所有View通用下拉刷新上拉加载控件
- Android自定义控件下拉刷新和加载更多
- 自个儿写Android的下拉刷新/上拉加载控件
- 打造Android万能下拉刷新上拉加载控件
- Android控件SwipeRefreshLayout实现下拉刷新上拉加载
- android自定义下拉刷新和上拉加载控件
- 打造Android万能下拉刷新上拉加载控件
- listView 模仿ios的上拉刷新下拉加载更多
- cocos2d-x 控件: 下拉框,(模仿CCMenu)
- 冒泡排序
- ARM主站-CANopenIO模块设计过程
- 关于二叉树宽度的算法包括递归和非递归
- 2012-2013 Waterloo Local Contest, 13 October, 2012 A题(最短路变形)
- django小记
- android模仿支付宝生活圈下拉加载控件TriangleLoadingView
- [windows] flask - sqlite3.OperationalError: unable to open database file
- 通过Docker和Rancher部署可扩展的Jenkins 集群
- 神奇的map
- 交换两个数的三种方法
- Java学习笔记
- ajax中文乱码
- VMware Convert Error: The size of all flat source disks will exceed the capacity of xxxxx
- 书评-----疯狂Java:突破程序员基本功的16课.李刚