当前位置:   article > 正文

Kotlin在Android端的使用方法_import kotlinx.android.synthetic

import kotlinx.android.synthetic

Kotlin相信现在大家都不陌生了,它是谷歌在5月18日,它的安卓团队在GoogleI/O 2017 大会上正式宣布 Kotlin 成为官方头等支持语言。最近一段时间我学习和研究了下Kotlin的特点和基本用法。大概用了一天时间,把Android的一些主要的APP功能,用Kotlin语言和结构重新写了一遍,体会就是:上手和学习很快、语法简洁、代码少写了很多、不用很麻烦的写控件绑定了(自动导包)、兼容性不错、空指针处理都帮你想好了、Java和Android的原来的框架和库都可以正常使用、支持Java和Kotlin混合编写等等。一些语法糖很好用。

Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发。Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。

先看下官网的一个最形象简单的例子。

Kotlin在Android端的使用方法

好吧,看到这里你会说没什么简洁的,感觉都差不多。

那我先总结下Kotlin中必要有特点的几个地方:

1、方法名fun开头、语句和声明结尾无需加分号了(当然加了也不报错)、方法参数和变量声明是反过来的:前面是名称,后面是类型,例如

var name:String?=null

2、对象的创建没有new了,直接对象名+括号。例如创建Utils这个类,然后调用它的foo方法:

  1. var utils = Utils();
  2. utils.foo(this);

3、控件直接不用findViewById了,直接对应布局里的控件id名字使用,会自动导包。

import kotlinx.android.synthetic.main.activity_main.*

4、重写父类方法由原来的@override注解改成了前缀。

  1. override fun onCreate(savedInstanceState: Bundle?) {
  2. super.onCreate(savedInstanceState)
  3. setContentView(R.layout.activity_main)
  4. initView();
  5. }

5、继承变成了冒号:分隔代替了extend,实现接口直接逗号,分隔代替了immplement。

  1. class MainActivity : BaseActivity(), View.OnClickListener {
  2. }

6、没有了switch case语句,取而代之是when ->语句,例如:

  1. override fun onClick(v: View?) {
  2. when (v!!.id) {
  3. R.id.tv_getdata -> {
  4. getData()
  5. }
  6. R.id.tv_intent -> {
  7. var intent = Intent(this@MainActivity, SencondActivity::class.java);
  8. intent.putExtra("name", "名字")
  9. intent.putExtra("id", 12)
  10. startActivity(intent)
  11. }
  12. }
  13. }

7、非空控制严格,更安全方便。!!、?。例如在使用!!后,使用的对象不可为空,空的时候直接抛出空指针异常;使用?后,使用的对象可以为空,空的时候返回Null。

  1. private var users: Call>? = null
  2. private var userList: List? = null

Intent意图的接收,直接intent接收,不用getIntent了。已经封装好,例如

  1. name = intent.getStringExtra("name")
  2. id = intent.getIntExtra("id", 1)

9、for循环的不同。例如i从0到9循环,添加到ArrayList

  1. for (i in 0..9) {
  2. list!!.add("" + i)
  3. }

也有这种,for(i in 对象集合.indices),例如

  1. for (i in userList!!.indices) {
  2. Log.i("info", "用户:" + userList!!.get(i).full_name);
  3. }

10、构造方法的不同,构造方法可以卸载类名后,如空的构造方法,后面会直接执行init方法,例如

  1. class ApiClient constructor() {
  2. private var apiservice: ApiService? = null;
  3. private var retrofit: Retrofit? = null;
  4. init {
  5. retrofit = Retrofit.Builder().baseUrl(Conf.BASE_URL)
  6. .addConverterFactory(GsonConverterFactory.create())
  7. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  8. .build();
  9. apiservice = retrofit!!.create(ApiService::class.java)
  10. }

当然有参的多个构造方法,也可以写在类里,例如

  1. constructor(resultListener: ResultListener) {
  2. this.resultListener = resultListener
  3. }
  4. constructor(context: Context, progress: Boolean, resultListener: ResultListener) {
  5. this.progress = progress
  6. this.resultListener = resultListener
  7. if (progress) {
  8. loadingView = LoadingView(context)
  9. loadingView!!.setOnCancelListener(this)
  10. }
  11. }

11、接口的定义。

  1. interface ResultListener {
  2. fun complete(t: T)
  3. fun onError(e: Throwable)
  4. }

12、对象实体的构建,不用setter和getter了,直接定义或者data class+对象名,例如:

  1. class User {
  2. var id: Int = 0
  3. var name: String? = null
  4. var full_name: String? = null
  5. var owner: OwnerBean? = null
  6. @SerializedName("private")
  7. var isPrivateX: Boolean = false
  8. var html_url: String? = null
  9. var description: String? = null
  10. var isFork: Boolean = false
  11. var url: String? = null
  12. var forks_url: String? = null
  13. var keys_url: String? = null
  14. var collaborators_url: String? = null
  15. var teams_url: String? = null
  16. var hooks_url: String? = null
  17. var issue_events_url: String? = null
  18. var events_url: String? = null
  19. var assignees_url: String? = null
  20. var branches_url: String? = null
  21. var tags_url: String? = null
  22. var blobs_url: String? = null
  23. var git_tags_url: String? = null
  24. var git_refs_url: String? = null
  25. var trees_url: String? = null
  26. var statuses_url: String? = null
  27. var languages_url: String? = null
  28. var stargazers_url: String? = null
  29. var contributors_url: String? = null
  30. var subscribers_url: String? = null
  31. var subscription_url: String? = null
  32. var commits_url: String? = null
  33. var git_commits_url: String? = null
  34. var comments_url: String? = null
  35. var issue_comment_url: String? = null
  36. var contents_url: String? = null
  37. var compare_url: String? = null
  38. var merges_url: String? = null
  39. var archive_url: String? = null
  40. var downloads_url: String? = null
  41. var issues_url: String? = null
  42. var pulls_url: String? = null
  43. var milestones_url: String? = null
  44. var notifications_url: String? = null
  45. var labels_url: String? = null
  46. var releases_url: String? = null
  47. var deployments_url: String? = null
  48. var created_at: String? = null
  49. var updated_at: String? = null
  50. var pushed_at: String? = null
  51. var git_url: String? = null
  52. var ssh_url: String? = null
  53. var clone_url: String? = null
  54. var svn_url: String? = null
  55. var homepage: String? = null
  56. var size: Int = 0
  57. var stargazers_count: Int = 0
  58. var watchers_count: Int = 0
  59. var language: String? = null
  60. var isHas_issues: Boolean = false
  61. var isHas_projects: Boolean = false
  62. var isHas_downloads: Boolean = false
  63. var isHas_wiki: Boolean = false
  64. var isHas_pages: Boolean = false
  65. var forks_count: Int = 0
  66. var mirror_url: Any? = null
  67. var isArchived: Boolean = false
  68. var open_issues_count: Int = 0
  69. var license: Any? = null
  70. var forks: Int = 0
  71. var open_issues: Int = 0
  72. var watchers: Int = 0
  73. var default_branch: String? = null
  74. class OwnerBean {
  75. var login: String? = null
  76. var id: Int = 0
  77. var avatar_url: String? = null
  78. var gravatar_id: String? = null
  79. var url: String? = null
  80. var html_url: String? = null
  81. var followers_url: String? = null
  82. var following_url: String? = null
  83. var gists_url: String? = null
  84. var starred_url: String? = null
  85. var subscriptions_url: String? = null
  86. var organizations_url: String? = null
  87. var repos_url: String? = null
  88. var events_url: String? = null
  89. var received_events_url: String? = null
  90. var type: String? = null
  91. var isSite_admin: Boolean = false
  92. }
  93. }

 13、BaseActivity的写法大家也应该可以大概猜到什么样式的。

  1. open class BaseActivity : AppCompatActivity() {
  2. override fun onCreate(savedInstanceState: Bundle?) {
  3. super.onCreate(savedInstanceState)
  4. }
  5. fun showToast(context: Context, text: String) {
  6. Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
  7. }
  8. /*
  9. * show toast in activity
  10. * */
  11. fun Activity.toast(msg: String){
  12. Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
  13. }
  14. override fun onResume() {
  15. super.onResume()
  16. }
  17. }

14、常量的定义,val表示常量,类似java里的final,常量定义后不能修改,var定义的可以修改。例如:

  1. object Conf {
  2. val BASE_URL: String? = "https://api.github.com/"
  3. }

15、多了Any这个任意数据类型,字符串支持三个引号""",也支持换行。例如:

  1. /*
  2. * kotlin对字符串的加强,三个引号"""中可以包含换行、反斜杠等等特殊字符
  3. * */
  4. fun testString() {
  5. val str1 = "abc"
  6. val str2 = """line1\n
  7. line2
  8. line3
  9. """
  10. val js = """
  11. function myFunction()
  12. {
  13. document.getElementById("demo").innerHTML="My First JavaScript Function";
  14. }
  15. """.trimIndent()
  16. println(str1)
  17. println(str2)
  18. println(js)
  19. }

好了,我总结的关键的大概这么多。都是实际实践操作中总结的比较突出的。

下面我粘贴部分我的写的例子的代码。完整的去Github上看。

Android Studio或者IntelliJ IDEA创建是选择Kotlin的,当然如果Android也可以,只不过需要自己手动在build.gradle等文件里添加一些Kotlin配置库。

先看BaseApplication.kt,很简单,里面其他逻辑没写。

  1. package com.gavin.kotlin.base
  2. import android.app.Application
  3. class BaseApplication : Application() {
  4. override fun onCreate() {
  5. super.onCreate()
  6. }
  7. }

BaseActivity.kt

  1. package com.gavin.kotlin.base
  2. import android.app.Activity
  3. import android.content.Context
  4. import android.os.Bundle
  5. import android.support.v7.app.AppCompatActivity
  6. import android.widget.Toast
  7. open class BaseActivity : AppCompatActivity() {
  8. override fun onCreate(savedInstanceState: Bundle?) {
  9. super.onCreate(savedInstanceState)
  10. }
  11. fun showToast(context: Context, text: String) {
  12. Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
  13. }
  14. /*
  15. * show toast in activity
  16. * */
  17. fun Activity.toast(msg: String){
  18. Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
  19. }
  20. override fun onResume() {
  21. super.onResume()
  22. }
  23. }

MainActivity.kt,里面接口网络请求数据使用了Retrofit和Rxjava:

  1. package com.gavin.kotlin.ui
  2. import android.content.Intent
  3. import android.os.Bundle
  4. import android.util.Log
  5. import android.view.View
  6. import com.bumptech.glide.Glide
  7. import com.gavin.kotlin.R
  8. import com.gavin.kotlin.base.BaseActivity
  9. import com.gavin.kotlin.entity.User
  10. import com.gavin.kotlin.net.ApiClient
  11. import com.gavin.kotlin.net.ResultListener
  12. import com.gavin.kotlin.net.ResultObserver
  13. import com.gavin.kotlin.utils.Utils
  14. import kotlinx.android.synthetic.main.activity_main.*
  15. import retrofit2.Call
  16. class MainActivity : BaseActivity(), View.OnClickListener {
  17. private var users: Call>? = null
  18. private var userList: List? = null
  19. override fun onCreate(savedInstanceState: Bundle?) {
  20. super.onCreate(savedInstanceState)
  21. setContentView(R.layout.activity_main)
  22. initView();
  23. }
  24. private fun initView() {
  25. var utils = Utils();
  26. utils.foo(this);
  27. tv_tips.setText("测试控件");
  28. utils.testString3();
  29. utils.testApply(this);
  30. utils.getPoint('B');
  31. Glide.with(this).load("http://file.qingyaoweb.com/d/file/shujuku/bznfjyxih4u.png").into(iv_img);
  32. Log.i("info", "测试输出Log");
  33. runOnUiThread(Runnable {
  34. kotlin.run {
  35. toast("测试弹出提示")
  36. }
  37. })
  38. tv_getdata.setOnClickListener(this);
  39. tv_intent.setOnClickListener(this)
  40. Utils().foo(this);
  41. ApiClient().getListRepo("1", ResultObserver(object : ResultListener> {
  42. override fun complete(t: List) {
  43. showToast(this@MainActivity, t.size.toString() + " " + t.get(0).full_name)
  44. }
  45. override fun onError(e: Throwable) {
  46. }
  47. }));
  48. }
  49. override fun onClick(v: View?) {
  50. when (v!!.id) {
  51. R.id.tv_getdata -> {
  52. getData()
  53. }
  54. R.id.tv_intent -> {
  55. var intent = Intent(this@MainActivity, SencondActivity::class.java);
  56. intent.putExtra("name", "名字")
  57. intent.putExtra("id", 12)
  58. startActivity(intent)
  59. }
  60. }
  61. }
  62. fun getData() {
  63. Thread(Runnable {
  64. users = ApiClient().getListRepo("1");
  65. userList = users!!.execute().body();
  66. for (i in userList!!.indices) {
  67. Log.i("info", "用户:" + userList!!.get(i).full_name);
  68. }
  69. }).start();
  70. }
  71. }

SecondActivity.kt

  1. import android.os.Bundle
  2. import android.support.v7.app.AppCompatActivity
  3. import android.support.v7.widget.LinearLayoutManager
  4. import android.support.v7.widget.OrientationHelper
  5. import com.gavin.kotlin.R
  6. import com.gavin.kotlin.adapter.ListAdapter
  7. import kotlinx.android.synthetic.main.activity_second.*
  8. class SencondActivity : AppCompatActivity() {
  9. private var name: String? = null
  10. private var id: Int? = null
  11. private var adapter: ListAdapter? = null
  12. private var layoutManager: LinearLayoutManager? = null
  13. private var list: ArrayList? = null
  14. override fun onCreate(savedInstanceState: Bundle?) {
  15. super.onCreate(savedInstanceState)
  16. setContentView(R.layout.activity_second)
  17. initView()
  18. }
  19. private fun initView() {
  20. name = intent.getStringExtra("name")
  21. id = intent.getIntExtra("id", 1)
  22. tv_intent.setText(name + " " + id)
  23. layoutManager = LinearLayoutManager(this)
  24. rv.setLayoutManager(layoutManager)
  25. layoutManager!!.orientation = OrientationHelper.VERTICAL
  26. list = ArrayList()
  27. for (i in 0..9) {
  28. list!!.add("" + i)
  29. }
  30. adapter = ListAdapter(this@SencondActivity, list!!);
  31. rv.setAdapter(adapter)
  32. }
  33. }

ListAdapter.kt

  1. package com.gavin.kotlin.adapter
  2. import android.content.Context
  3. import android.support.v7.widget.RecyclerView
  4. import android.support.v7.widget.RecyclerView.ViewHolder
  5. import android.view.LayoutInflater
  6. import android.view.View
  7. import android.view.ViewGroup
  8. import android.widget.TextView
  9. import com.gavin.kotlin.R
  10. class ListAdapter(private val mContext: Context, private val mDatas: List) : RecyclerView.Adapter() {
  11. private var inflater: LayoutInflater? = null
  12. override fun getItemCount(): Int {
  13. return mDatas!!.size
  14. }
  15. override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
  16. holder.tv.text = mDatas!![position]
  17. }
  18. override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
  19. inflater = LayoutInflater.from(mContext)
  20. val view = inflater!!.inflate(R.layout.item_list, parent, false)
  21. return MyViewHolder(view)
  22. }
  23. class MyViewHolder(view: View) : ViewHolder(view) {
  24. var tv: TextView
  25. init {
  26. tv = view.findViewById(R.id.tv_text)
  27. }
  28. }
  29. }

Conf.kt

  1. package com.gavin.kotlin.base
  2. object Conf {
  3. val BASE_URL: String? = "https://api.github.com/"
  4. }

LoadingView.kt

  1. package com.gavin.kotlin.views
  2. import android.app.Dialog
  3. import android.content.Context
  4. import android.content.DialogInterface
  5. import android.view.Gravity
  6. import android.view.WindowManager
  7. import com.gavin.kotlin.R
  8. class LoadingView : Dialog {
  9. constructor(context: Context) : super(context) {
  10. init(context)
  11. }
  12. constructor(context: Context, themeResId: Int) : super(context, R.style.Loading) {
  13. init(context)
  14. }
  15. protected constructor(context: Context, cancelable: Boolean, cancelListener: DialogInterface.OnCancelListener) : super(context, cancelable, cancelListener) {
  16. init(context)
  17. }
  18. private fun init(context: Context) {
  19. setContentView(R.layout.layout_loading)
  20. setCanceledOnTouchOutside(false)
  21. val lp = window!!.attributes
  22. lp.width = WindowManager.LayoutParams.WRAP_CONTENT
  23. lp.height = WindowManager.LayoutParams.WRAP_CONTENT
  24. lp.gravity = Gravity.CENTER
  25. lp.dimAmount = 0f
  26. window!!.attributes = lp
  27. }
  28. }

ApiClient.kt,retrofit和rxjava写法

  1. package com.gavin.kotlin.net
  2. import com.gavin.kotlin.base.Conf
  3. import com.gavin.kotlin.entity.User
  4. import io.reactivex.Observable
  5. import io.reactivex.Observer
  6. import io.reactivex.android.schedulers.AndroidSchedulers
  7. import io.reactivex.schedulers.Schedulers
  8. import retrofit2.Call
  9. import retrofit2.Retrofit
  10. import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
  11. import retrofit2.converter.gson.GsonConverterFactory
  12. class ApiClient constructor() {
  13. private var apiservice: ApiService? = null;
  14. private var retrofit: Retrofit? = null;
  15. init {
  16. retrofit = Retrofit.Builder().baseUrl(Conf.BASE_URL)
  17. .addConverterFactory(GsonConverterFactory.create())
  18. .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
  19. .build();
  20. apiservice = retrofit!!.create(ApiService::class.java)
  21. }
  22. fun getListRepo(id: String): Call> {
  23. return apiservice!!.listRepos(id);
  24. }
  25. private fun subscribeOnobserveOn(observable: Observable, observer: Observer) {
  26. observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(observer)
  27. }
  28. fun getListRepo(id: String, resultObserver: ResultObserver>) {
  29. subscribeOnobserveOn(apiservice!!.getUserList(id), resultObserver)
  30. }
  31. }

ApiService.kt写法:

  1. import com.gavin.kotlin.entity.User
  2. import io.reactivex.Observable
  3. import retrofit2.Call
  4. import retrofit2.http.GET
  5. import retrofit2.http.Path
  6. interface ApiService {
  7. @GET("users/{user}/repos")
  8. fun listRepos(@Path("user") user: String): Call>
  9. @GET("users/{user}/repos")
  10. fun getUserList(@Path("user") user: String): Observable>
  11. }

Utils.kt,这里面的测试例子

  1. package com.gavin.kotlin.utils
  2. import android.app.Activity
  3. import android.content.Context
  4. import android.content.pm.PackageInfo
  5. import android.content.pm.PackageManager
  6. import android.widget.ImageView
  7. import android.widget.TextView
  8. import android.widget.Toast
  9. class Utils {
  10. fun foo(context: Context) {
  11. Toast.makeText(context, "文本", Toast.LENGTH_LONG).show();
  12. print("成员函数Foo")
  13. } // 成员函数
  14. fun demo(x: Any) {
  15. if (x is String) {
  16. print(x.length) // x 自动转换为字符串
  17. }
  18. }
  19. /*
  20. * kotlin对字符串的加强,三个引号"""中可以包含换行、反斜杠等等特殊字符
  21. * */
  22. fun testString() {
  23. val str1 = "abc"
  24. val str2 = """line1\n
  25. line2
  26. line3
  27. """
  28. val js = """
  29. function myFunction()
  30. {
  31. document.getElementById("demo").innerHTML="My First JavaScript Function";
  32. }
  33. """.trimIndent()
  34. println(str1)
  35. println(str2)
  36. println(js)
  37. }
  38. /*
  39. * kotlin字符串模版,可以用$符号拼接变量和表达式
  40. * */
  41. fun testString2() {
  42. val strings = arrayListOf("abc", "efd", "gfg")
  43. println("First content is $strings")
  44. println("First content is ${strings[0]}")
  45. println("First content is ${if (strings.size > 0) strings[0] else "null"}")
  46. }
  47. /*
  48. *Kotlin中,美元符号$是特殊字符,在字符串中不能直接显示,必须经过转义,方法1是用反斜杠,方法二是${'$'}
  49. * */
  50. fun testString3() {
  51. println("First content is \$strings")
  52. println("First content is ${'$'}strings")
  53. }
  54. /*
  55. * 用apply语句简化类的初始化,在类实例化的时候,就可以通过apply把需要初始化的步骤全部实现,非常的简洁
  56. * */
  57. fun testApply(context: Context) {
  58. var imgView = ImageView(context).apply {
  59. setBackgroundColor(0)
  60. setImageBitmap(null)
  61. }
  62. var textView = TextView(context).apply {
  63. text = "content"
  64. textSize = 20.0f
  65. setPadding(10, 0, 0, 0)
  66. }
  67. }
  68. fun test01() {
  69. val list = listOf(2, 5, 10)
  70. /*
  71. * 传人函数来过滤
  72. * */
  73. println(list.filter { it > 4 })
  74. }
  75. /*
  76. * kotlin中,when是表达式,可以取代Java 中的switch,when的每个分支的最后一行为当前分支的值
  77. * */
  78. fun getPoint(grade: Char) = when (grade) {
  79. 'A' -> "GOOD"
  80. 'B', 'C' -> {
  81. println("test when")
  82. "OK"
  83. }
  84. 'D' -> "BAD"
  85. else -> "UN_KNOW"
  86. }
  87. /*
  88. * show toast in activity
  89. * */
  90. fun Activity.toast(msg: String) {
  91. Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
  92. }
  93. /**
  94. * 获取版本号VersionCode
  95. */
  96. fun getVersionCode(context: Context): Int {
  97. val packageManager = context.packageManager
  98. val packageInfo: PackageInfo
  99. var versionCode = ""
  100. try {
  101. packageInfo = packageManager.getPackageInfo(context.packageName, 0)
  102. versionCode = packageInfo.versionCode.toString() + ""
  103. } catch (e: PackageManager.NameNotFoundException) {
  104. e.printStackTrace()
  105. }
  106. return Integer.parseInt(versionCode)
  107. }
  108. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/277380
推荐阅读
相关标签
  

闽ICP备14008679号