最近几周(20200907)Android项目遇到的问题总结

215 阅读4分钟

1 自定义view 的手势缩放,具体参看下面这个链接

juejin.cn/post/684490…

这个demo中,定义了常见的收拾缩放逻辑,同时能够从github上下载demo,注释也相对详细,是手势入门中,我找到的比较好的demo。


2 自定view 画笔基础:

www.gcssloop.com/customview/…

上面这篇文章详细介绍了自定义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次元魔法师,可以关注一波。

这是一个非常详细的Matrix介绍

canvas作用到matrix上的有关方法

canvas.concat 作用到 matrix上

canvas.mapPoints 作用到 matrix上

Android 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就表示灰色。

如何用10行代码让app全局置灰

文中从 原生view开始思考,逐步实现了 ViewGroup, 再到构建 BaseActivity 实现整个应用的灰度化。非常简洁明了。

8 圆角图片实现的四种种方式

1 在layout中添加遮盖
2 使用 BitmapShader
3 使用 Xfermode
4 使用 RoudedBitmapDrawable (使用 BitmapShader实现)