用Kotlin和Anko实现安卓UI(二)

时间:2021-11-22 22:42:08
设计项目的外观
     Anko为我们提供了在单独的Kotlin类中为Activity使用UI的便利。因此,每个屏幕都可以被认为是Kotlin类的UI-Activity匹配对。这个UI类是通过继承在org.jetbrains.anko包中定义的AnkoComponent<T>接口的功能来实现的。      除了这个接口,JetBrains还提供免费的DSL 布局预览功能。下面是Anko DSL布局预览在Android Studio中的样子:
   用Kotlin和Anko实现安卓UI(二)
        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] 查看源文件 复制代码
 
         override fun createView(ui: AnkoContext<MainActivity>): View = with(ui) {
         }
        我们在 createView ( )   方法中UI定义返回给所有者即activity,在这里也就是MainActivity,所以接下来写 createView ( )   方法:
        Step1-设计首页       用Kotlin和Anko实现安卓UI(二)       最初,首页是空列表。所以,我们有一个textView要求用户创建一天的Todo List: [Java] 查看源文件 复制代码
return relativeLayout {        
                         //声明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()        
                   }
       }
          centerInParent ( 是将视图的布局定义为垂直和水平相对中心的辅助方法。 因为它是一个todo性质的应用,其本质在于显示任务的列表。所以,我们在这里定义 listView
[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,否则隐藏他
[Java] 查看源文件 复制代码
 
//显示或隐藏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 我们会看到对话框:
       用Kotlin和Anko实现安卓UI(二)
         而一旦我们添加了几个任务,我们可以看到任务列表:
         用Kotlin和Anko实现安卓UI(二)
      Step3-删除任务             
       请记住,我们已经在TodoAdapter类中定义了从列表中删除项目的方法delete(Int)现在是设计UI的时候,这又会调用这个方法。遵循Android设计模式,我们可以做一个任务点击后选择何种处理的选项列表。所以,我们来定义一个列表项长按事onLongClick