Android面试系列文章2018之Android部分之自定义View篇

Android fragment中自定义view重构 android自定义view面试题_Android

1.自定义View需要具备的知识点

View坐标系

Android的角度与弧度

View绘制机制

View事件分发

Android动画机制

Canvas类

Path类

2.自定义View的几种方式

《Android艺术探索》给出的三种方式

a.对原View进行扩展方式

b.多个View的组合方式

c.重写View的方式

2.1 自定义View

继承View类

继承特殊的View类,如:TextView

2.2 自定义ViewGroup

继承ViewGroup类

继承特殊的ViewGroup,如:LinearLayout

组合View&ViewGroup的特殊类

3.自定义View/ViewGroup

3.1 自定义属性

自定义属性的步骤如下:

1.分析需要的自定义属性

2.在项目下res/values/attrs.xml定义声明

3.在layout xml中进行使用

4.在自定义View的构造方法中进行获取

Android fragment中自定义view重构 android自定义view面试题_Android_02

Android fragment中自定义view重构 android自定义view面试题_android 自定义方形章_03

详细的自定义属性相关知识

解析自定义属性

3.2 常用的方法&类介绍

View测量:

a.MeasureSpec的解析:解析父View传递过来MeasureSpec的size和mode,然后在结合View自身的宽高,最终确认View的宽高和MeasSpec。

b.setMeasuredDimension():这个方法的作用就是存储测量后的宽和高,在自定义View时,它的重要性也不必笔者啰嗦了吧!

c.requestLayout():调用此方法后强制性重新进行measure过程和layout过程。

View绘制:

a.invalidate()&postInvalidate(): invalidate()函数的主要作用是请求View树进行重绘,该函数可以由应用程序调用,或者由系统函数间接调用,例如setEnable(), setSelected(), setVisiblity()都会间接调用到invalidate()来请求View树重绘,更新View树的显示,注意的是如果是自定义View时此方法是不允许在子线程调用的,因此postInvalidate()方法就是用来弥补invalidate()不能在子线程调用的缺点,postInvalidate()可以在子线程中调用,作用和invalidate()是一样的。

b.Canvas.drawXXX:Canvas是画布的意思,它是用来绘制各种图形文本等。

c.translate()&rotate()&scale()&skew():这4个方法都是Canvas提供的4个方法,就是将画布进行平移,旋转,缩放,错切,关于这4个方法详细了解,请点击此链接。

d.save()&restore():save()方法就是用来保存Canvas的状态,而restore()方法是用来恢复save()方法保存时候的状态,在它们调用的间隔之间,可以调用translate()&rotate()&scale()&skew()以达到一些比较好的效果。

View状态备份与恢复

a.onSaveInstanceState():重写此方法,通过Bundle来保存当前View的状态,但是要注意的是通常我们自定义View都会基础某个特定的View,因此我们在重写onSaveInstanceState()时注意2点,第1点就是备份当前View的状态,第2点就是保持父类的备份机制。代码如下:

Android fragment中自定义view重构 android自定义view面试题_自定义属性_04

b.onRestoreInstanceState():重写此方法,通过Bundle来恢复当前的状态,还是同样需要恢复父类备份的那部分状态。代码如下:

Android fragment中自定义view重构 android自定义view面试题_Android_05

c.为什么有时候我们重写了onSaveInstanceState()&onRestoreInstanceState()来备份和恢复这个自定义View的状态时会出现无效的情况,那极有可能是你在使用它是没有加上id属性,因为Android备份和恢复View状态的前提是你得给这个View一个id。

3.3 支持特殊的属性

3.3.1 warp_content

3.3.2 padding

3.3.3 margin

3.4 内存泄漏

3.4.1 管理子线程

3.4.2 动画的开启/停止

3.5 滑动嵌套(事件分发有关)

4.给出一些自定义View的案例

https://blog..net/wingichoy/article/details/50455412

https://blog..net/qq_26787115/article/details/50831506