当前位置: 首页 > 科技观察

一觉醒来,Kotlin成了Android的新宠【附代码】

时间:2023-03-12 16:43:53 科技观察

前言凌晨的GoogleI/O2017开发者大会直播你看了吗?尽管Android已成为移动设备最流行的操作系统,但在全球范围内采用Android操作系统的活跃设备已超过20亿。不过对于谷歌来说,Android开发是否需要依赖java一直是个心头大的问题,因为java和谷歌在Android系统上的官司让oracle筋疲力尽。现在好了,Google正式支持Kotlin作为官方认可的Android开发语言,并且从AndroidStudio3.0开始,将直接集成Kotlin,无需安装任何插件。Text开始做AndroidUI开发,一直使用XML文件实现。虽然理论上可以用Java语言来实现UI,但是用处不大。不久前,JetBrains推出了Kotlin,这是一种面向JVM的现代语言,可以很好地实现AndroidUI。Jetbrains声称Anko是Android中更快、更容易的开发风格。Kotlin提供Anko库作为DSL(领域特定语言)来设计Android界面。一个简单的例子:下面的界面由一张图片和一个按钮组成:使用Anko实现如下:verticalLayout{imageView(R.drawable.anko_logo).lparams(width=matchParent){padding=dip(20)margin=dip(15)}button("TaptoLike"){onClick{toast("Thanksforthelove!")}}}我们定义一个垂直的线性布局作为一个容器来包含图片和按钮,使用lparams定义布局的位置信息,以及按钮点击事件也是通过Kotlin的内联函数实现的。使用Anko的优势:我们可以将UI布局嵌入到代码中,从而使其成为类型安全的。因为我们不是用XML编写,所以它提高了效率,因为CPU时间浪费在了解析XML上。在对UI进行编程化改造后,我们可以将AnkoDSL片段放入一个函数中。这有利于代码重用。显然,代码更加简洁,更具可读性和易掌握性。现在我们使用AnkoLayout和Kotlin构建一个待办应用程序来列出我们今天需要做的事情。你可以在GitHub上找到这个项目将Anko库添加到AndroidStudio:streamline-android-java-code-with-kotlin来学习如何将Kotlin添加到你的Android项目中,使用Kotlin,我们需要在应用中添加Anko依赖/build.gradle这样我们就可以顺利编译项目了。compile[size=1em]'org.jetbrains.anko:anko-sdk15:0.8.3'//sdk19,21,23也可以根据你项目的minSdkVersion来添加这个依赖。上面的例子说明15<=minSdkVersion<19,你可以在Anko的GitHub仓库中找到你需要的其他Anko依赖。我们将使用以下依赖库:compile'org.jetbrains.anko:anko-design:0.8.3'compile'org.jetbrains.anko:anko-appcompat-v7:0.8.3'在Activity:我们已经不用XML写布局文件了,所以我们不需要XMLView,所以我们也不需要findViewById()方法。这里我们假设我们的Anko布局类是MainUI,然后我们就可以开始写我们的activit内容了:varui=MainUI()//MainUI类替换了XML布局ui.setContentView(this)//这代表了Activity类现在我们创建一个Kotlin文件MainActivity.kt,写入如下代码:{valarrayList=savedInstanceState.get("ToDoList")task_list.addAll(arrayListasList)}varadapter=TodoAdapter(task_list)//定义适配器varui=MainUI(adapter)//定义要使用的AnkoUI布局ui.setContentView(this)//为Activity设置Anko布局}overridefunonSaveInstanceState(outState:Bundle?){outState?.putStringArrayList("ToDoList",task_list)super.onSaveInstanceState(outState)}}task_list是一个ArrayList,会填充TodoAdapter的列表视图。MainUI(adapter)是我们的AnkoUI文件,它将TodoAdapter类作为适配器参数。所以,接下来我们创建一个TodoAdapter类。ListView的TodoAdapter适配器TodoAdapter类有一个类型为ArrayList的列表,并继承自BaseAdapter。所以我们需要重写四个方法:publicintgetCount()publicObjectgetItem(inti)publiclonggetItemId(inti)publicViewgetView(inti,Viewview,ViewGroupviewGroup)在getView()方法中我们需要使用Anko设计表格元素布局。publicintgetCount()publicObjectgetItem(inti)publiclonggetItemId(inti)publicViewgetView(inti,Viewview,ViewGroupviewGroup)在getView()方法中我们需要使用Anko来设计表格元素的布局。overridedefungetView(i:Int,v:View?,parent:ViewGroup?):View{returnwith(parent!!.context){//任务数从1开始vartaskNum:Int=i+1//列表表格元素布局linearLayout{lparams(width=matchParent,height=wrapContent)padding=dip(10)orientation=HORIZONTAL//任务号textView{id=R.id.taskNumtext=""+taskNumtextSize=16ftypeface=Typeface.MONOSPACEpadding=dip(5)}//taskNametextView{id=R.id.taskNametext=list.get(i)textSize=16ftypeface=DEFAULT_BOLDpadding=dip(5)}}}}在这个方法中,我们返回一个包含horizo??ntalListView布局列表项的视图。这是使用Kotlin的with语法完成的,它允许我们一次调用对象实例上的许多方法。每个列表项包含两个文本视图,用于显示任务编号和任务名称。linearLayout,textView是扩展功能。扩展函数使我们能够为任何类启用新功能。text、textSize、typeface在android.widget.TextView中有getter和setter方法,padding是Anko添加的属性。继续下一步,我们需要定义列表操作函数。因此,我们需要在TodoAdapter中定义add(String)和delete(Int)方法。add(String)将任务名称作为参数添加到任务中。delete(Int)以任务的位置为参数删除任务。下面是具体实现://向任务列表添加任务的方法funadd(text:String){list.add(list.size,text)notifyDataSetChanged()//更新数据}//从任务中移动任务list添加的方法是fundelete(i:Int){list.removeAt(i)notifyDataSetChanged()//updatedata}所以,既然我们已经设计好了列表,我们也可以在我们的列表中添加和删除项目。接下来完成此适配器类的代码。TodoAdapter(vallist:ArrayList=ArrayList()):BaseAdapter(){overridefungetView(i:Int,v:View?,parent:ViewGroup?):View{returnwith(parent!!.context){//taskNumwillserveatheS.No.oftheliststartingfrom1vartaskNum:Int=i+1//LayoutforalistviewitemlinearLayout{id=R.id.listItemContainerlparams(width=matchParent,height=wrapContent)padding=dip(10)orientation=HORIZONTALtextView{id=R.id.taskNumtext=""+taskNumtextSize=16ftypeface=Typeface.MONOSPACEpadding=dip(5)}textView{id=R.id.taskNametext=list.get(i)textSize=16ftypeface=DEFAULT_BOLDpadding=dip(5)}}}}overridefungetItem(位置:Int):String{returnlist[position}overridefungetCount():Int{returnlist.size}overridefungetItemId(position:Int):Long{//可以用来returntheitem'sIDcolumnoftableeturn0L}//functiontoaddanitemtothelistfunadd(text:String){list.add(list.size,text)notifyDataSetChanged()}//functiontodeleteanitemfromlistfundelete(i:Int){list.removeAt(i)notifyDataSetChanged()}}注意,使用AnkoDSL类必须导入org.jetbrains.anko.*来设计项目的外观Anko为我们提供了在单独的Kotlin类中使用Activity的UI的便利。因此,每个屏幕都可以被认为是Kotlin类的匹配UI-Activity对。这个UI类是通过继承org.jetbrains.anko包中定义的AnkoComponent接口的功能来实现的。除了这个界面,JetBrains还提供了免费的DSL布局预览功能。这是AnkoDSLLayoutPreview在AndroidStudio中的样子:可以从这里下载AnkoPreview的相应插件。请注意,AndroidStudio2.2的AnkoDSL布局预览在撰写本文时被列为开源问题。言归正传,我们接下来设计MainUI类来展示所有的任务列表。MainUI类继承AnkoComponent接口,其中T指的是UI的所有者,活动的内容将是UI。在我们的例子中,所有者是我们在上面定义的MainActivity。接下来,在初始化时,我们必须将TodAadapter对象传递给此类,因为此适配器将用于填充列表。因此,MainUI声明变为:classMainUI(valtodoAdapter:TodoAdapter):AnkoComponent现在我们需要重写方法createView(),它接受一个AnkoContext对象作为参数并返回一个View类型:overridefuncreateView(ui:AnkoContext):View=with(ui){}在createView()方法中,UI定义返回给owner,也就是activity,也就是这里的MainActivity,所以接下来写createView()方法:Step1-设计主页最初,主页是一个空列表。所以,我们有一个textView要求用户创建一天的待办事项列表:returnrelativeLayout{//declareListViewvartodoList:ListView?=null//当没有任务时显示textView内容valhintListView=textView("What'syourTodoListfortoday?"){textSize=20f}.lparams{centerInParent()}}centerInParent()是一个辅助方法,它定义视图的布局相对于中心垂直和水平。因为它是一个todo应用,它的本质就是展示一个任务列表。所以,我们在这里定义listView://listViewverticalLayout{todoList=listView{//assignadapteradapter=todoAdapter}}.lparams{margin=dip(5)}todoAdapter是我们在MainUI类声明中定义的一个成员变量。我们使用todoAdapter的值初始化listView的适配器,它是将用于填充列表的TodoAdpater类的一个对象。为了帮助用户添加任务,我们在主屏幕的右下方提供了一个MaterialDesign风格的floatingActionButton。所以我们使用Anko将floatingActionButton编程为:floatingActionButton{imageResource=android.R.drawable.ic_input_add}.lparams{//设置按钮在屏幕右下方margin=dip(10)alignParentBottom()alignParentEnd()alignParentRight()gravity=Gravity.BOTTOMorGravity.END}篇幅有限,Step2、Step3请点击左下角“阅读原文”查看所有文章。***想法在开发这个待办事项应用程序时,我们没有使用任何XML布局资源,但我们能够以类似的风格设计该应用程序。Anko从应用程序的活动或片段中移除呈现数据、响应用户交互、连接数据库等的负担。此外,隔离UI和Activity类使应用程序更接近MVP(模型-视图-呈现器)架构。您可以在这里了解Anko的高级功能。虽然它有一些缺点,比如编译速度慢和应用程序体积大,因为它在重用、维护和测试代码方面打包了很多。第一次手工翻译这么长的文章。如有错误,敬请指出,见谅!也是因为对Kotlin的兴趣,才找到这篇文章进行翻译。有兴趣的朋友可以看看学习一下。