anko写可重用的style

问题

安卓使用xml布局时,
style是省略大部分代码的一个工具,
然而转向anko后发现并没有这么容易了.
anko不再支持style这样的写法.

方案

anko有apply函数和applyRecursively函数.
可以作为style的备用实现方案

目标

  1. 能影响外观
  2. 能像原先一样继承

实现

变化

  1. xml中是定义式编程,而使用anko来实现是函数式编程,需要转换一些写法
  2. kotlin特有的类型判断以及类似rust的类型判断后对类型的隐式转换大有用途
  3. 要发挥applyRecursively的特长,把原来一些组合使用Label,content的style放在一处

举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 继承举例
fun FontBase(view: View) {
if (view is TextView) {
view.setTypeface(null, Typeface.BOLD)
// 在if外部,view还不被认为是TextView,还不能调用textColor
view.textColor = ContextCompat.getColor(view.context, R.color.textPrimary)
}
}

fun Label(view: View) {
if (view is TextView) {
FontBase(view)
view.textSize = 20f
}
}

fun LabelAndLongEt(view: View) {
when (view) {
// kotlin的when会自动break
// EditText是TextView的子类,如果先判断,
// 会导致EditText使用的是父类的效果并且break出去了
// 因此要子类优先判断
is EditText ->
LongET(view)
is TextView ->
Label(view)
}
}

anko中一些效果的新写法

类别 写法
width view.width = view.dip(90)
gravity view.gravity = Gravity.END // 用end代替了right
textColor view.textColor = ContextCompat.getColor(view.context, R.color.textPrimary)
textSize view.textSize = 24f // anko的textSize自动选择了sp作为单位
width view.layoutParams.width = matchParent
height view.layoutParams.height = wrapContent
15dp view.dip(15)
15sp view.sp(15) // 写是可以写但不用
padding view.horizontalPadding = view.dip(15) // 对称时,anko可以用一个横向padding代替左右
textStyle view.setTypeface(null, Typeface.BOLD)
background view.setBackgroundResource(R.drawable.out~framebackground~)
inputType view.inputType = InputType.TYPE~CLASSNUMBER~
maxLength view.filters += InputFilter.LengthFilter(4) // 注意是加等于
imeOptions view.imeOptions = EditorInfo.IME~ACTIONDONE~
selectAllOnFocus view.setSelectAllOnFocus(true)
nextFocusForwardId view.nextFocusForwardId = R.id.package~s~
digit keyListener = DigitsKeyListener.getInstance(“0123456789.”)