Android 自定义View——随移动距离改变弧度布局
来源:互联网 发布:知乎 圣诞 编辑:程序博客网 时间:2024/06/10 02:42
PullArcLayout
简介
下拉可以随手指移动距离改变弧度的布局——Git地址ArcContainer
先看看效果吧
思路如下
这个效果的最初始是因为项目中的需求效果,写完之后觉得还不错。就把思路整理了一下,顺便记录一下自己的想法。
- 原项目中使用的下拉框架在这里就不在做展示,而使用YListview做替代。其实讲内部原理的话都是差不多的,就是在下拉的过程中,顶部的View不停调用setLayoutParams方法,从而使布局的高度不断改变。
而setLayoutParams方法的内部则会调用requestLayout方法,从而让View不断的重新绘制。- 使用Canvas在下拉过程中不断的绘制出特定的Path,以及Paint的setXfermode()方法提供的混合模式。
- 还有一个知识点:
- 自定义View,时一般重写的话会选择onDraw()方法。而ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法。
1.先把需要的对象创建出来,尤其注意Xfermode的模式选择
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.WHITE); mClipPath = new Path();
2.在onMeasure()方法里,绘制Path路径
- 基本样子是介个样子的,如图中橘色线框起来的部分:
- 在这里遇到一个不大不小的坑。因为弧形使用贝塞尔二阶曲线绘制的,但最开始的时候弧形的顶点总是短了那么一点点。让人很是费解,但其实贝塞尔的曲线是这样的:
也就是说弧顶的距离其实比参数设置里的距离是要短一些的,经过一些调试,最终在onMeasure代码实现如下:
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); width = getMeasuredWidth(); height = getMeasuredHeight(); if (firstGetHeight) { orignalHeight = height; firstGetHeight = false; } mClipPath.rewind(); mClipPath.moveTo(0, orignalHeight); mClipPath.cubicTo(0, orignalHeight, width / 2, orignalHeight + 2.2f * (height - orignalHeight), width, orignalHeight); mClipPath.lineTo(width, height); mClipPath.lineTo(0, height); mClipPath.close(); }
3.在dispatchDraw()方法中将path绘制出来
@Override protected void dispatchDraw(Canvas canvas) { //绘制保存在新的图层 int saveCount = canvas.saveLayer(0, 0, getMeasuredWidth(), getMeasuredHeight(), null, Canvas.ALL_SAVE_FLAG); super.dispatchDraw(canvas); // 2017/2/23-11:27 设置新的混合模式 mPaint.setXfermode(porterDuffXfermode); // 2017/2/23-11:28 绘制 canvas.drawPath(mClipPath, mPaint); // 2017/2/23-11:28 还原混合模式 mPaint.setXfermode(null); // 2017/2/23-11:28 还原画布 canvas.restoreToCount(saveCount); }
有关Path的小知识点
- rewind()方法和reset()方法的区别
reset清除path上的内容,重置path到 path = new Path()的初始状态。
rewind清除path上的内容,但会保留path上相关的数据结构,以高效的复用。
感谢以下开源项目:
- YListView
0 0
- Android 自定义View——随移动距离改变弧度布局
- Android自定义View基础——弧度和角度
- android学习6#--自定义View之颜色与角度弧度
- Android自定义View(二)__角度和弧度的区别
- Android自定义View基础(二)-角度与弧度
- Android——自定义View随手自由移动
- Android--View自定义—标签<流式布局>
- 百分比布局,android自定义View。
- android 自定义View 梯形布局
- android 自定义VIew 动态在页面中改变页面的布局
- Android—自定义view
- 安卓自定义 View 基础:角度弧度
- 自定义View基础:角度与弧度
- 自定义View(三) 角度和弧度
- Android自定义卫星弧度菜单
- Android中自定义View,自定义布局
- Android自定义View 一个可设置四个顶点弧度的ImageView
- CoordubatirLayout简单使用2,移动自定义布局改变动画
- Android-mediaRecorder(媒体录像器)实例
- 浏览器的本地存储
- uC/OS-II源码入门分析
- nginx upstream的五种分配方式
- 集合的类型和各自的特性
- Android 自定义View——随移动距离改变弧度布局
- 为什么引入线程
- 课程学习归纳总结(0223)
- 爬虫-漫画喵的100行逆袭
- Java 去除小数点后面多余的0
- 顺序表的有关操作
- 内存流 数据流 打印流的简单使用
- 文章标题
- LeetCode 33. Search in Rotated Sorted Array