事例介绍
记得以前很容易写出一个自定义view,如果很长时间没有写,是很容易生疏的,一般自定义view有组合的viewgroup,有从最小单元的view入手,而这次要写的自定义选词填空view是从view出发的,在做之前也搜过相关的view,大部分都是从textview的span入手的,但是textview的span写的话,会遇到各种问题,很难得去扩展,因此下定决心自己要写一个跟自己产品相关的选词填空view。先直接看做出来的效果:

在这里分为两种类型的选词填空题,分为解析类和做题类,解析类只会显示答案的正确与否,做题类型会直接把选项填上去的场景。而在做题类会有两种情况:
- 选项少于空格:这种是选项选了之后还可以选择
- 选项多余空格:这种是选项选了之后不能选择
实现的功能:
- 能实现空格的选中
- 切换选中的空格
- 优先将选项填到选中的空格,如果没有选中的空格,则默认从第一个空格开始
- 如果该空格已经有答案填了,则再次选中该空格的时候会还原该空格的答案,还原选项的是否可选的状态。
大概的逻辑就是上面几点了,虽然说是很清楚,但是自定义view会涉及到文字的换行,下划线的换行,非答案的文字测量,答案的文字测量,下划线的测量,而下划线的测量是根据有没有答案来测量的,在有答案的时候,会根据答案的长度来绘制下划线的,没有答案的时候,会给下划线一个默认的长度。
关于文字的测量有:
- 先根据paint.breakText方法算出当前宽度内能容纳几个文字,该方法会返回wordCount数量
- 紧接着根据string的substring截取文字
- 将截取的文字添加到文字的集合中
绘制:
- 由于上面已经算出了每一行文字的信息,因此在绘制过程中直接取文字的集合,遇到文字绘制文字,遇到下划线绘制下划线。
触摸:
- 由于需要交互,因此重写了onTouch的up事件,在up的时候先获取到是否点击了下划线部分,如果点击了则判断该处时候已经选了答案,如果选择了则重置答案,否则选中该处的下划线部分。
- 触摸选项的时候会遍历下划线,如果有选中的下划线部分,则直接填充答案给该下划线部分,如果没有选中的下划线,则直接遍历下划线集合,找到了没有答案的下划线的时候,直接将选中的选项填充到该下划线部分。
是否onMeasure过程:
- 在填充行信息的时候,会记录住上次的view的总高度,如果当前和上次的总高度发生了变化,则进行
requestLayout
,否则直接invalidate
。 - 在onMeasure的时候,主要是在mode为非exactly的时候需要重新设置了高度和宽度。
使用:
- 如果想直接有流失布局的选项样式直接用:
<com.xc.blank.BlankRootView
android:id="@+id/blank_root_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- 如果想自己定义选项的view那你可以直接定义BlankView:
<com.xc.blank.BlankView
android:id="@+id/blankView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_23"
android:layout_marginTop="20dp"
android:layout_marginRight="@dimen/dp_16"/>
后期会考虑加入自定义属性!!!
如果想第一时间看demo效果扫描下面二维码:

github地址:进入