Kotlin开发Android应⽤实例详解
Kotlin开发Android应⽤实例详解
相关⽂章:关于Kotlin语⾔的基础介绍:
我们简单的知道了Kotlin这门新语⾔的优势,也接触了⼀些常见的语法及其简单的使⽤,相信你会对它有浓厚的兴趣,暂且理解为对它感兴趣吧,哈哈哈。那么,我们该如何在Android中应⽤这门新的语⾔呢?今天的这篇⽂章带你学习使⽤Kotlin开发Android应⽤,并对⽐我们传统语⾔Java,让你真真切切的感受到他的美和优雅。
配置
apocalyp
项⽬gradle⽂件
1 2 3 4 5 6 7apply plugin: 'com.android.application'
apply plugin:'kotlin-android'
apply plugin:'kotlin-android-extensions' dependencies {
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.1.1' }
app Gradle⽂件:
1 2 3compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1.1'
compile 'org.jetbrains.anko:anko-sdk25:0.10.0-beta-1'// sdk15, sdk19, sdk21, sdk23 are also available compile 'org.jetbrains.anko:anko-appcompat-v7:0.10.0-beta-1'
Anko
通过上⾯的配置,你会发现引⼊的有anko的依赖。Anko是JetBrains开发的⼀个强⼤的库,说起JetBrains ,那就⽜逼了,Kotlin语⾔是他们开发的,最流⾏的的开发⼯具intellij idea都是他们开发的,AS也是基于IDEA的。好了,⾔归正传,Anko是Kotlin官⽅开发的⼀个让开发Android应⽤更快速更简单的Kotlin库,并且能让我们书写的代码更简单清楚更容易阅读。它包括多个部分,如下
1 2 3 4Anko Commons: a lightweight library full of helpers for intents, dialogs, logging and so on; Anko Layouts: a fast and type-safe way to write dynamic Android layouts;
Anko SQLite: a query DSL and parr collection for Android SQLite;
Anko Coroutines: utilities bad on utines library
那么接下来,我们就通过代码来理解Kotlin语⾔开发Android的优势所在。
再也不⽤findViewById
做过Android开发的⼈都知道,布局⽂件写的多了,findViewById也是⼀个很⼤的⼯作量,⽽且还要先声明变量,在findViewById然后再强转成我们的控件,使⽤⽅式⼀般如下
1 2 3 4TextView urname;
urname=(TextView)findViewById(R.id.ur); urname.tText("我是⼀个TextView");
有时候写的是不是想吐,可能有些⼈说现在不是有⼀些注解的库,如butterknife,当我们使⽤注解时可以不⽤findViewById了,使⽤⽅式如下
免费翻译软件1 2 3 4@BindView(R.id.ur)
TextView urname;
urname.tText("我是⼀个TextView");
确实是这样,使⽤注解后确实给我们少了⼀些⼯作量,不过这依然没有最简单化,最简单的就是我们可以直接给id为ur的控件直接赋值,或许你会感觉这有点不可思议。不过Kotlin确实做到了。我们可以直接这样写
<="我是⼀个TextView"
看到这你是不是有⼀种相见恨晚的感觉,太Tama的简洁了。ur就是我们布局⽂件声明的id,.text就想当与tText()给,在Kotlin语⾔中,我们看不到了像Java中的t/get⽅法了。需要注意的是,当我们想这样使⽤的时候(不⽤findViewById,直接使⽤xml控件我们需要在gradle 加⼊apply plugin: ‘kotlin-android-extensions'),需要加⼊下⾯⼀句代码
1 2//activity_login就是我们的布局
import kotlinx.android.synthetic.main.activity_login.*
Anko Layout
通常我们使⽤xml⽂件写我们的布局,但是他有⼀些缺点如不是类型安全,不是空安全,解析xml⽂件消耗更多的CPU和电量等等。⽽Anko Layout可以使⽤DSL动态创建我们的UI,并且它⽐我们使⽤Java动态创建布局⽅便很多主要是更简洁,它和拥有xml创建布局的层级关系,能让我们更容易阅读。
1 2 3 4 5 6 7verticalLayout {
val textView=textView("我是⼀个TextView") val name = editText("EditText")
button("Button") {
onClick { toast("${}!") }
}
}
我们在OnCreate⽅法中可以去掉tContentView,然后加⼊上⾯代码就可以显⽰如下图的效果,即⼀个垂直的线性布局中,放了⼀个TextView,⼀个EditText,和⼀个Button。并且Button中有⼀个点击事件,当点击时将EditText的内容
以toast显⽰。
上⾯的代码是不是很简单易懂,当然,默认的控件并不能满⾜我们的需求,例如我们会更改字体的颜⾊及⼤⼩,会设置宽度和⾼度,会设置margin,padding值,那么该如何实⾏呢,当然也很简单,因
为它的逻辑和xml书写布局是⼀个套路。例如以下实现
1 2 3 4 5 6 7 8val textView=textView("我是⼀个TextView"){
textSize = sp(17).toFloat()
d) }.lparams{
margin=dip(10)
height= dip(40)
width= matchParent
}
我想我不需要说明上⾯的代码,你就应该看得出控件实⾏的效果。因为它的属性和我们在xml设置属性的名字对应的。
在上⾯创建UI过程中,我们直接把创建UI的代码写在onCreate⽅法中了,当然,还有⼀种写法。我们创建⼀个内部类实⾏AnkoComponent 接⼝,并重写createView⽅法,该⽅法返回⼀个View,也就是
我们创建的布局。修改如下
1
2
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22inner class UI : AnkoComponent<LoginActivity> {
override fun createView(ui: AnkoContext<LoginActivity>): View { return with(ui){
verticalLayout {
val textView=textView("我是⼀个TextView"){
textSize = sp(17).toFloat()
d)
}.lparams{
margin=dip(10)
height= dip(40)
width= matchParent
}
val name = editText("EditText")
button("Button") {
onClick { view ->
toast("Hello, ${}!")
}
}
}
}
}
}
然后在onCreate⽅法中加⼀句代码,即可创建我们的布局页⾯了。如下
1UI().tContentView(this@LoginActivity)
mwie现在我们编译运⾏,发现效果和布局⽂件写的界⾯是⼀样的。但是它的性能是有优势的,其实吧并没有发觉性能优势。不管怎样,这种DSL 确实便于阅读,也很容易上⼿,在上⾯的代码中,你可能注意到了dip(10),它表⽰将10dp转换为像素的意思,是Anko的扩展函数,说的扩展函数,如果阅读过Anko的源码我们发现⾥⾯⼤量的使⽤扩展函数,这也是Kotlin语⾔的优势之⼀。确实很强⼤,例如dip扩展(摘取View扩展)
1 2inline fun View.dip(value: Int): Int = context.dip(value)
during的用法fun Context.dip(value: Int): Int = (value * resources.displayMetrics.density).toInt()
在上⾯resources.displayMetrics.density和我们Java getResources().getDisplayMetrics().density是⼀个效果,不过看着你会不会感觉⽐Java 书写舒服多了,反正我是这么感觉的。
在上⾯的我们给Button加了⼀个点击事件,我们发现它⽀持lambda表达式。我们想显⽰⼀个Toast,只需要toast(“内容”)就可以了,是不是⼜很简洁。其实它也是扩展函数,实现
1 2inline fun AnkoContext<*>.toast(message: CharSequence) = ast(message)
ast(message: CharSequence) = Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
当然创建dialog依然也很简单,如下
1 2 3 4alert ("我是Dialog"){
yesButton { toast("yes")} noButton { toast("no")} }.show()
真是越看越舒⼼,哈哈。再来⼀个强⼤⽽⼜很简单很简单很简洁的⼀段代码实现。
1 2 3 4 5 6doAsync {
//后台执⾏代码
uiThread {
//UI线程
toast("线程${Thread.currentThread().name}") } }
该段代码实现的就是AsyncTask 的效果,但是你应该发现它⽐Java的实现简洁多了,当然除⾮是⾊盲,要不然你会看出简洁的。
如果你使⽤Kotlin开发Android⼀段时间后,会发现它给我们减少了很多的代码量,当然更多的优势及⽤法需要我们⾃⼰去探索。相信经过探索后它会让你⼤吃⼀惊。
实现⼀个简单的登录界⾯
界⾯很简单,伪代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<LinearLayout>
<ImageView/>
<LinearLayout> <ImageView/><EditText账号/><LinearLayout>
<LinearLayout> <ImageView/><EditText密码/><LinearLayout>
<Button 登录/>
<LinearLayout> <CheckBox 记住密码/><TextView 隐私协议xieu/><LinearLayout> <TextView/>
bevix</LinearLayout>
不缪
看着并不复杂的,那么xml实现的代码就不在这贴出了,如果你想看xml实现可看点击查,那么接下来来只看Anko在Kotlin代码中实现这个布局。
1
2
3
4
5
6
7
8
9 10 11 12 13 14 15 16 17 18 19 20lateinit var et_account: EditText
lateinit var et_password: EditText
inner class LoginUi : AnkoComponent<LoginActivity> {
override fun createView(ui: AnkoContext<LoginActivity>) = with(ui) { verticalLayout {
backgroundColor = Color(lor.white) gravity = Gravity.CENTER_HORIZONTAL
imageView(R.mipmap.ic_launcher).lparams {
width = dip(100)
height = dip(100)
topMargin = dip(64)
}
linearLayout {
jason earles21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 gravity = Gravity.CENTER_VERTICAL
orientation = HORIZONTAL
backgroundResource = R.drawable.bg_frame_corner
imageView {
image = Drawable(R.mipmap.ic_urname)
}.lparams(width = wrapContent, height = wrapContent) {
leftMargin = dip(12)
rightMargin = dip(15)
}resistant是什么意思
et_account = editText {
hint = "登录账户"
hintTextColor = Color.parColor("#666666")
textSize = 16f
background = null
}
}.lparams(width = dip(300), height = dip(40)) {
topMargin = dip(45)
}
linearLayout {
orientation = HORIZONTAL
backgroundResource = R.drawable.bg_frame_corner
gravity = Gravity.CENTER_VERTICAL
imageView {
image = Drawable(R.mipmap.ic_password)
}.lparams {
leftMargin = dip(12)
rightMargin = dip(15)
}
et_password = editText {
hint = "登录密码"
hintTextColor = Color.parColor("#666666")
textSize = 16f
background = null
}
}.lparams {
width = dip(300)
height = dip(40)
topMargin = dip(10)
}
button("登录") {
gravity = Gravity.CENTER
background = Drawable(R.drawable.bg_login_btn)
textColor = Color.parColor("#ffffff")
onClick {
if(oString().isNotEmpty() && oString().isNotEmpty()) startActivity<MainActivity>() el toast("请输⼊账户或者密码")
}
}.lparams(width = dip(300), height = dip(44)) {
topMargin = dip(18)
}
linearLayout {
orientation = HORIZONTAL
gravity = Gravity.CENTER_VERTICAL
checkBox("记住密码") {
textColor = Color.parColor("#666666")
textSize = 16f
leftPadding = dip(5)
}
textView("隐私协议") {
textColor = Color.parColor("#1783e3")
gravity = Gravity.RIGHT
textSize = 16f
}.lparams(width = matchParent)
}.lparams(width = dip(300)) {
topMargin = dip(18)
}
textView("Copyright © Code4Android") {
textSize = 14f
gravity = Gravity.CENTER or Gravity.BOTTOM
}.lparams {
bottomMargin = dip(35)
weight = 1f
}
}
}
}
89
90
91
92
93
胜利日之吻
94
95
看到上⾯的代码怎么样,看起来还不错吧,即使现在你不会写,但是你也能读懂它。在上⾯我们给登录按钮设置⼀个打开MainActivity的事件。startActivity的<>中写的是我们要跳转的Activity,如果给打开的界⾯传递参数,直接写在()中。例如我们将输⼊的账号和密码传到跳转的界⾯,则实现为
1startActivity<MainActivity>("account"to oString(),"password"to oString())
其实Anko的强⼤之处远不⽌于此,值得我们细细品味。sicca
感谢阅读,希望能帮助到⼤家,谢谢⼤家对本站的⽀持!
如对本⽂有疑问,请提交到交流社区,⼴⼤热⼼⽹友会为你解答!!