1 自定义view 的手势缩放,具体参看下面这个链接
这个demo中,定义了常见的收拾缩放逻辑,同时能够从github上下载demo,注释也相对详细,是手势入门中,我找到的比较好的demo。
2 自定view 画笔基础:
上面这篇文章详细介绍了自定义view中画笔的属性和设置。非常详细。
3 自定义view 实现属性动画
实现思路:
1 自定义属性,并添加 set get 方法
2 添加ObjectAnimator, 对该属性设置动画的数值。
3 在 onDraw中,根据对应的属性,绘制对应的内容。
4 在set方法中,调用 invalidate。即可完成动态重绘。
具体参看hencoder的这篇文章:hencoder.com/ui-1-6/
4 自定义view踩过的坑
1 canvas.drawPath 无效
1.在自定义view中,添加设置
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
2.在清单文件中 ,activity 或者application 中添加
android:hardwareAccelerated="false"
2 自定义view中,绘制多条线段卡顿
1 通常绘制线段的时候,我们会使用 path.lineto/moveto 方法。这两个方法,在绘制较少的线段的时候没问题,但在绘制多条line的时候会有卡顿的情况发生。
2 这时候可以使用 Canvas.drawLines() 他能够绘制多条线段。理由如下:
Paths are always rendered using the CPU.
When the app is hardware accelerated this means the renderer will first draw your path using the CPU into a bitmap,
then upload that bitmap as a texture to the GPU and finally draw the texture on screen.
具体参考链接:stackoverflow.com/questions/1…
canvas.drawLines() 使用方法及逐一实现如下,其中,第一个参数必须是4的倍数的数组,具体参看下面第二条链接: www.jcodecraeer.com/a/anzhuokai… blog.csdn.net/pimkle/arti…
踩过的其他坑
1 存储访问错误 open failed: EACCES (Permission denied):
www.jianshu.com/p/d349047e6… 除了在 manifest中声明权限之外,还需要在 6.0之上的版本动态申请,否则报错。
2 setLayoutParams()无效问题
我开始使用的是view.getLayoutParams(),然后修改对应属性后,又重新设置回了 view.setLayoutParams()。
由于两次的 layoutParams 是同一个引用,所以系统可能会认为 layoutparams未发生改变。所以我们new LayoutParams(),重新设置给View。
具体参看: blog.csdn.net/qq_19269585…
3 TextVeiw 设置 sp 和 dp 的区别
当修改系统字体大小时,
- 字体大小以dp为单位时,大小不变;
- 字体大小以sp为单位时,大小跟随变化;
具体参看:www.jianshu.com/p/e89bc2890…
4 在拉伸/压缩过的canvas上,设置pivotX/Y
当canvas 被拉伸或者压缩之后,我们如果用两个手指继续操作拉伸/缩放的操作。可以通过下面连接中提到方法进行设置中心点。
setPivotX works strange on scaled View
5 Matrix 相关操作
Android Matrix利用invert实现逆向坐标映射
下面这个链接的作者写的博客非常棒,2.5次元魔法师,可以关注一波。
canvas作用到matrix上的有关方法
6 View onAttachedToWindow 和 onDetachedFromWindos调用时机
在项目中经常会用到自定义view,当界面销毁的时候,自定义view的一些资源要进行初始化、销毁或者重置。 这些操作的时机是非常重要的。
onAttachedToWindow 调用过程
ActivityThread.handleResumeActivity()
↓
WindowManager.addView()
↓
WindowManagerImpl.addView()
↓
WindowManagerGlobal.addView()
↓
root.setView(view,wparams,panelParentView) 这里 root 就是 ViewRootImpl
↓
ViewRootImpl.performTranversals() 触发view 的 三段式方法 measure, layout, draw
↓
host.dispatchAttachedToWindow(mAttachInfo, 0) host是 Activity的DecorView(FrameLayout)的子类。
↓
viewGroup.dispatchAttachedToWindow
↓
view.dispatchAttachedToWindow
同理, view 的 onDetachedFromWindow 调用过程
ActivityThread.handleDestroyActivity()
↓
WindowManager.removeViewImediate()
↓
WindowManager.removeViewLocked()
↓
ViewRootImp.die()
↓
ViewRootImp.doDie()
↓
ViewRootImpl.dispatchDetachedFromWindow()
↓
viewGroup.dispatchDetachedFromWindow()
↓
view.dispatchDetachedFromWindow()
View onAttachedToWindow 和 onDetachedFromWindos调用时机
7 如何让view变成灰色
之前总结过,对bitmap加上颜色过滤器,绘制到canvas上,显现出不同的颜色。这次是对某一个view进行处理。 简而言之,就是对view设置饱和度 setSaturation, 设置值为0就表示灰色。
文中从 原生view开始思考,逐步实现了 ViewGroup, 再到构建 BaseActivity 实现整个应用的灰度化。非常简洁明了。
8 圆角图片实现的四种种方式
1 在layout中添加遮盖
2 使用 BitmapShader
3 使用 Xfermode
4 使用 RoudedBitmapDrawable (使用 BitmapShader实现)
-
不规则图形的绘制,波浪黑板擦(黑板擦的实现不是像我们想的那么简单)