参考:Android官网:https://developer.android.google.cn
一、Kotlin特性
1、变量
var count: Int = 10
var :变量count :变量名Int :整型,类似的还有:Byte、Short、Long、Float 和 Double注意 :声明的时候,如果不使用类型推断,则变量名和变量类型使用英文冒号连为一体。使用的时候,只需要使用变量名即可。句尾不需要写分号。 如: count=20
2、常量
val languageName: String = “Kotlin”
把var的r 改成l 即可,但是不可再次赋值,因为是常量。
3、类型推断:
val languageName = “Kotlin”
val upperCaseName = languageName.toUpperCase()
显然languageName 是字符串String 类型 在 声明变量 的时候,可以 只赋值,而省略掉 变量的类型。 此时,系统会根据 赋值的字面值 来推断该变量的数据类型,从而节省代码量。
4、null类型限制:
//错误示范: val languageName: String = null
- 注意:以上代码
错误 。 - 原因:Kotlin语言对变量的null类型进行了限制,
默认情况下,变量不能为null类型 ,也就是变量必须要有对应变量类型的值。 - 废话:这种方式虽然让Kotlin语言难了一点,但是保证了代码的安全(因为如果变量的值为null,并且被程序使用,可能会让应用无故崩溃闪退,这是谁也不愿意看到的)
//正确示范:类型后面加个问号即可 val languageName: String? = null
上面的String? 表示:变量可以拥有两种类型: 1、String类型:可以把字符串赋值给它 2、null类型:可以把null赋值给它
5、分支(条件语句)
5.1 分支1:if-else
if (count == 42) {
println("I have the answer.")
} else {
println("The answer eludes me.")
}
if (count == 42) {
println("I have the answer.")
} else if (count > 35) {
println("The answer is close.")
} else {
println("The answer eludes me.")
}
val answerString: String = if (count == 42) {
"I have the answer."
} else if (count > 35) {
"The answer is close."
} else {
"The answer eludes me."
}
println(answerString)
if-else语句中最后一个字面值,都可以表示为该分支(最终只有一条为真)的返回值。
上面的语句的意思就是使用一个变量来接受if-else分支结构的返回值。
在一定程度上减少了println的代码
5.2 分支2:when、else、-> 的搭配
when{} 条件-> 语句 else->语句
val answerString = when {
count == 42 -> "I have the answer."
count > 35 -> "The answer is close."
else -> "The answer eludes me."
}
println(answerString)
6、函数:
6.1 声明定义:
fun generateAnswerString(): String {
val answerString = if (count == 42) {
"I have the answer."
} else {
"The answer eludes me"
}
return answerString
}
fun generateAnswerString(countThreshold: Int): String {
val answerString = if (count > countThreshold) {
"I have the answer."
} else {
"The answer eludes me."
}
return answerString
}
6.2 特性简化:
fun generateAnswerString(countThreshold: Int): String {
return if (count > countThreshold) {
"I have the answer."
} else {
"The answer eludes me."
}
}
fun generateAnswerString(countThreshold: Int): String = if (count > countThreshold) {
"I have the answer"
} else {
"The answer eludes me"
}
6.3 匿名函数:
val stringLengthFunc: (String) -> Int = { input ->
input.length
}
1、常量val,变量名为stringLengthFunc,这个变量用来干嘛呢?看它冒号后面的
数据类型,(String) -> Int,这个可能最难理解。
(参数类型)->函数返回值类型
1、首先,小括号我们可以理解成函数,因为函数的函数名后面常常都携带一个小括号。
至于这里为什么没有函数名?因为这是匿名函数呀,自然要省略函数名。
2、其次,箭头和后面的Int又是什么意思呢?我们都知道,函数有两个非常重要的组成部分
一个是函数名,另一个是函数返回类型。因为是匿名函数,所以函数名没了,
而函数返回类型却不能省略,所以,Int这里就是它的函数返回类型。
2、后面的赋值符号=又是什么意思:
这就是前面说的,省略return,使用赋值符号取而代之的骚操作,
没有return的时候就不会这样写了,所以他就是return的简写版而已。
3、最后面的:input ->
input.length
其实这就像lambda表达式一样,input是实参,箭头后面才是函数体。
注意:如果匿名函数没有返回值(自然也就没有return),那就会相当于全部省略,
只保留大括号,让人难以看出。今后要是遇到匿名函数,要心里留个底
避免傻傻看不出。
6.4 高阶函数:参数有函数的
fun stringMapper(str: String, mapper: (String) -> Int): Int {
return mapper(str)
}
mapper:函数引用(你可以理解成一个函数指针)
stringMapper("Android", { input ->
input.length
})
stringMapper("Android") { input ->
input.length
}
7、类(属性+函数)
属性默认权限:public
class Car {
val wheels = listOf<Wheel>()
}
构造函数的构建:
class Car(val wheels: List<Wheel>){...}
构造函数可以直接在声明类的类名后面当作函数一样传入函数参数
类的实例化(使用构造函数)、类对象的属性的调用:
val car = Car()
val wheels = car.wheels
类函数:
class Car(val wheels: List<Wheel>) {
private val doorLock: DoorLock = ...
fun unlockDoor(key: Key): Boolean {
}
}
二、Kotlin在安卓开发中常见的代码总结:
1、使用 Fragment
class LoginFragment : Fragment()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.login_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
2、推迟变量的初始化:late-init
class LoginFragment : Fragment() {
private lateinit var usernameEditText: EditText
private lateinit var passwordEditText: EditText
private lateinit var loginButton: Button
private lateinit var statusTextView: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
usernameEditText = view.findViewById(R.id.username_edit_text)
passwordEditText = view.findViewById(R.id.password_edit_text)
loginButton = view.findViewById(R.id.login_button)
statusTextView = view.findViewById(R.id.status_text_view)
}
...
}
3、事件的匿名函数:
loginButton.setOnClickListener {
val authSuccessful: Boolean = viewModel.authenticate(
usernameEditText.text.toString(),
passwordEditText.text.toString()
)
if (authSuccessful) {
} else {
statusTextView.text = requireContext().getString(R.string.auth_failed)
}
}
4、伴生对象:companion object
class LoginFragment : Fragment() {
...
companion object {
private const val TAG = "LoginFragment"
}
}
5、属性委托:by
注意:属性委托使用反射,这样会增加一些性能开销。这种代价换来的是简洁的语法,可让您节省开发时间。
private val viewModel: LoginViewModel by viewModels()
6、null的注意:
6.1 在Java中书写习惯:方便与kotlin协同
public class Account implements Parcelable {
public final String name;
public final String type;
private final @Nullable String accessId;
...
}
public class Account implements Parcelable {
public final @NonNull String name;
...
}
6.2 处理kotlin中的null值:
1、变量后面带 !! 运算符:
断定name为非null,强制执行,但如果为null就会报异常。所以这种写法其实回到了Java的模式上了。
val account = Account("name", "type")
val accountName = account.name!!.trim()
2、更安全的写法:?. +?:
val account = Account("name", "type")
val accountName = account.name?.trim()
val accountName = account.name?.trim() ?: "Default name"
骚操作:
fun validateAccount(account: Account?) {
val accountName = account?.name?.trim() ?: "Default name"
account ?: return
...
}
7、变量初始化:
7.1 在类声明的时候直接初始化:
class LoginFragment : Fragment() {
val index: Int = 12
}
7.2 在init块中初始化
class LoginFragment : Fragment() {
val index: Int
init {
index = 12
}
}
7.3 先null,后面尽快初始化
class LoginFragment : Fragment() {
private var statusTextView: TextView? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
statusTextView = view.findViewById(R.id.status_text_view)
statusTextView?.setText(R.string.auth_failed)
}
}
7.4 lateinit延迟初始化:比上一个好
class LoginFragment : Fragment() {
private lateinit var statusTextView: TextView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
statusTextView = view.findViewById(R.id.status_text_view)
statusTextView.setText(R.string.auth_failed)
}
}
|