Anko为我们提供了在单独的Kotlin类中为Activity使用UI的便利。因此,每个屏幕都可以被认为是Kotlin类的UI-Activity匹配对。这个UI类是通过继承在org.jetbrains.anko包中定义的AnkoComponent<T>接口的功能来实现的。 除了这个接口,JetBrains还提供免费的DSL 布局预览功能。下面是Anko DSL布局预览在Android Studio中的样子:
Anko Preview的相应插件可以从 这里下载 。请注意,在撰写本文时,Android Studio 2.2的Anko DSL 布局预览被列为开源 issue 。
回到正题,我们接下来设计 MainUI类展示 所有任务列表。 MainUI 类继承了 AnkoComponent < T > 接口,其中T指的是UI的所有者,activity的内容将会是这个UI。在我们的例子中,所有者就是我们已经在上面定义的 MainActivity 。接下来,在初始化时,我们必须将 TodAadapter 对象传递给此类,因为此适配器将用于填充列表。所以, MainUI 声明变成:
[Java] 查看源文件 复制代码
class MainUI(val todoAdapter : TodoAdapter) : AnkoComponent<MainActivity>
现在我们需要重写方法 createView ( ) ,使用 AnkoContext 对象作为参数并返回一个 View 类型:
[Java] 查看源文件 复制代码
我们在 createView ( ) 方法中UI定义返回给所有者即activity,在这里也就是MainActivity,所以接下来写 createView ( ) 方法:
override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) {
}
Step1-设计首页 最初,首页是空列表。所以,我们有一个textView要求用户创建一天的Todo List: [Java] 查看源文件 复制代码
return relativeLayout {centerInParent ( ) 是将视图的布局定义为垂直和水平相对中心的辅助方法。 因为它是一个todo性质的应用,其本质在于显示任务的列表。所以,我们在这里定义 listView :
//声明ListView
var todoList : ListView? =null
//当没有任务时显示textView内容"What's your Todo List for today?"
val hintListView = textView("What's your Todo List for today?") {
textSize = 20f
}.lparams {
centerInParent()
}
}
[Java] 查看源文件 复制代码
//listView
verticalLayout {
todoList=listView {
//assign adapter
adapter = todoAdapter
}
}.lparams {
margin = dip(5)
}
todoAdapter是我们在MainUI类声明中定义成员变量。我们用todoAdapter的值初始化listView的adapter,这是一个TodoAdpater类的对象,将会用于填充列表。
为了帮助用户添加任务,我们在主屏幕的右下方提供了一个Material design风格的floatingActionButton。所以我们使用Anko编程floatingActionButton为:
[Java] 查看源文件 复制代码
floatingActionButton {
imageResource = android.R.drawable.ic_input_add
}.lparams {
//设置按钮在屏幕的右下方
margin = dip(10)
alignParentBottom()
alignParentEnd()
alignParentRight()
gravity = Gravity.BOTTOM or Gravity.END
}
Step2- 显示添加任务的对话框
Anko提供了一种简单的方式来设置 View的点击监听 。因此,我们可以添加 onClickListener 到 floatingActionButton 通过实现里面的 onClick ( ) 方法。接下来我们创建一个在点击添加时出现的自定义对话框,这将要求用户输入任务并将其添加到列表中: [Java] 查看源文件 复制代码
floatingActionButton {
imageResource = android.R.drawable.ic_input_add
onClick {
val adapter = todoList?.adapter as TodoAdapter
alert {
customView {
verticalLayout {
//对话框标题
toolbar {
id = R.id.dialog_toolbar lparams(width = matchParent, height = wrapContent)
backgroundColor = ContextCompat.getColor(ctx, R.color.colorAccent)
title = "What's your next milestone?" setTitleTextColor(ContextCompat.getColor(ctx, android.R.color.white))
}
val task = editText {
hint = "To do task "
padding = dip(20)
}
positiveButton("Add") {
if(task.text.toString().isEmpty()) {
toast("Oops!! Your task says nothing!")
} else {
adapter.add(task.text.toString()) showHideHintListView(todoList!!)
}
}
}
}
}.show()
}
}.lparams {
/ /设置按钮显示在屏幕右下方
margin = dip(10)
alignParentBottom() alignParentEnd() alignParentRight()
gravity = Gravity.BOTTOM or Gravity.END
}
- alert{}是创建Anko对话框的内联函数。默认情况下,在Anko对话框中,我们可以设置一个文本消息并提供一个postiveButton和 negativeButton。我们还可以使用自定义警报对话框customView。
- verticalLayout是一个垂直方向的线性布局。
- 我们已经使用对话框toolbar添加了标题,从而进行了定制。请注意,我们如何在对话框中为视图分配颜色: backgroundColor =ContextCompat.getColor(ctx, R.color.colorAccent)。这里ctx指在包org.jetbrains.anko的AlertDialogBuilder类中定义的Context,我们需要其作为参数传递,以便让Android知道我们所指的上下文。
- postiveButton()是一种Anko辅助方法,可以让我们定义当用户提交对话框时会发生什么。这里我们检查是否task不为空,然后我们使用我们在TodoAdapter类中定义的add方法将任务添加到列表适配器。
-
showHideHintListView(todoList!!)是什么?这是一种我们为隐藏在主屏幕上的textView的方法,以便为我们的列表腾出空间。当listView为空时,我们会显示hintListView,否则隐藏他。
//显示或隐藏textView的方法
fun showHideHintListView(listView: ListView) {
if (getTotalListItems(listView)>0) {
hintListView.visibility = View.GONE
} else {
hintListView.visibility = View.VISIBLE
}
}
这里 getTotalListItems ( listView ) 是 MainUI类的成员方法, 返回在listView中的项目(task)数。它的Kotlin的普通方法:
[Java] 查看源文件 复制代码
//返回listView中的总项目(task)数
fun getTotalListItems(list: ListView?) = list?.adapter?.count ?: 0
最后点击 floatingActionButton 我们会看到对话框:
而一旦我们添加了几个任务,我们可以看到任务列表:
Step3-删除任务
请记住,我们已经在TodoAdapter类中定义了从列表中删除项目的方法delete(Int)。现在是设计UI的时候,这又会调用这个方法。遵循Android设计模式,我们可以做一个任务点击后选择何种处理的选项列表。所以,我们来定义一个列表项长按事onLongClick