掌握 Anko,看这一篇就够了!

平时开发android时,我们的UI布局代码一般都是写在xml中,当然也有少数写在Java代码中,这就导致了这样的局面:xml布局清晰可见,但不能动态改变,Java代码布局比较灵活,但比较难用而且冗余难维护,所以一般都是用xml先编排出布局,然后再用代码进行进一步修改搭配使用。那么有没有更清晰且高效的方式呢?有!Anko就很好的解决了这个问题。
一、Anko是什么?
Anko是JetBrains开发的一个强大的库,它主要的目的是用来替代以前XML的方式来使用代码生成UI布局的,它包含了很多的非常有帮助的函数和属性来避免让你写很多的模版代码。
这是一个很有趣的特性,我推荐你可以尝试下,但是在该系列文章里我们暂时不太多使用它(只在一些地方使用并会做好相关的解释),因为对于现阶段的我们来说使用XML更容易一些,而且Anko其实并不难,看这一篇你就能学会如何使用常用的Anko方法来优化代码了,所以我们会把更多的重点放到Kotlin的学习上来。
如果你想研究Anko源码一探究竟,点击我这里给出的Github传送。
二、开始使用Anko
首先让我们来使用Anko简化一些代码:
val recyclerView: RecyclerView = find(R.id.recyclerView)
以上代码写在MainActivity:onCreate中,这是一段用来简化获取RecyclerView的代码。就像你将要看到的,任何时候你使用了Anko库中的某些东西,它们都会以属性名、方法等方式被导入。
你可能会问:“find()这个方法是哪里来的?”这是因为Anko使用了扩展函数在Android框架中增加了一些新的功能。
而至于什么是扩展函数,暂时我们只要知道:“有了它我们就能在Actvity里面直接调用 verticalLayout( )、relativeLayout( )等方法”就可以了,因为这些都是Anko给Activity加的扩展方法,所以在activity内部可以直接调用到这些方法(比如这里的find())。
关于什么是扩展函数,可以看这篇文章:。。。
我们将会在之后的文章中更加详细介绍给大家一些其它的扩展函数并教会大家怎么去编写自己的扩展函数,所以还请点击绿色的加号保持对我的关注!
(1)我们再来看一个加载布局的例子:
verticalLayout {val name = editText()button("Say Hello") {onClick { toast("Hello, ${name.text}!") }
}
上面是一个DSL(Domain Specific Language),使用的是 Kotlin语言,作用是创建了一个Button,放在 LinearLayout 内,并为其设置了一个点击监听器onClick。
在这个加载布局的例子中,button 方法接了一个字符串参数,这样的 Helper 方法同样适用于 TextView、EditText、ImageView。
如果我们不需要 View 其它的属性,我们可以省略 “{}” 直接写 “button(“Ok”)” 或只有 “button()”,如下:
verticalLayout {button("Ok")button("Cancel")
}
- 关于控件显示文本问题:
虽然我们的正式编码中不会存在例程中这样的HardCode,因为我们一般会使用Java的字符串来进行相应的替换,但是大多数时候字符串都是放在 res/values/ 目录下的,并且是运行时调用的,例如:getString(R.string.login)。
幸运的是,Anko中可以使用这样的两个 helper 方法:“button(R.string.login)” 和 “button{textResource = R.string.login}”。
注意,这些属性不是 “text,hint,image”, 而是“textResource,hintResource,imageResource”。
番外:什么是DSL?
Domain Specific Language,即“领域相关语言”,说白了它就是某个行业中的行话。
举个例子:
在构建证券交易系统的过程中,在证券交易活动中存在许多专业的金融术语和过程。现在要为该交易过程创建一个软件解决方案,那么开发者/构建者就必须了解证券交易活动,其中涉及到哪些对象、它们之间的规则以及约束条件是怎么样的。那么就让领域专家(这里就是证券交易专家)来描述证券交易活动中涉及的活动。但是领域专家习惯使用他们熟练使用的行业术语来表达,解决方案的构建者无法理解。如果解决方案的模型构建者要理解交易活动,就必须让领域专家用双方都能理解的自然语言来解释。这种解释的过程中,解决方案的模型构建者就理解了领域知识。这个过程中双方使用的语言就被称为“共同语言”。
在上面的描述,可以看到在需求收集的过程中,如果要成功构建模型,则需要一种领域专家和构建者(也就是通常的领域分析师/业务分析师)都能理解的“共同语言”。但是这种共同语言的创建过程没有保证,不能够保证在收集过程中得到的信息完整的描述了领域活动中所有的业务规则和活动。
如果能够让领域专家通过简单的编程方式描述领域中的所有活动和规则,那么就能在一定程度上保证描述的完整性。DSL 就是为了解决这个问题而提出的。DSL 的特点:
- 用于专门领域,不能用于其他领域
- 表现力有限
- 不描述解答域,仅描述问题域DSL 与通用编程语言的区别:
- DSL 有更高级的抽象,不涉及类似数据结构的细节
- DSL 表现力有限,其只能描述该领域的模型,而通用编程语言能够描述任意的模型
好了,书归正传,我们再举一个设置布局参数的例子。
(2)在“onCreate()”中加载线性布局:
注意:我们不需要继承其它的类,只要标准的Activity、Fragment、FragmentActivity 就好。
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)verticalLayout {padding = dip(30)editText {hint = "Name"textSize = 24f}editText {hint = "Password"textSize = 24f}button("Login") {textSize = 26f}}
}
我们会发现,我们不需要显示的调用 setContentView(R.layout.something) , Anko 自动为Activity且只会对Activity进行 “set content view”,这一点我们会在Anko的源码中看到,下文会有解释。
扩展属性
这里的padding、 hint、textSize 是 扩展属性。大多数 View 都具有这些属性,并且允许使用text = "Some text"来代替setText("Some text")。扩展函数
上述代码中的verticalLayout是一个竖直方向的 LinearLayout,其中的editText和 button 都是 扩展函数。这些函数存在于 Android 框架中的大部 View 中:Activities、Fragments (android.support包中的) 甚至 Context 也同样适用。所以如果有一个 Context 实例的话,我们可以写出下面的DSL结构
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
