• <rp id="vcwyv"></rp>

      <b id="vcwyv"></b>
      <tt id="vcwyv"></tt>

    1. 使用Kotlin來開發Android【安卓巴士博文大賽】 [復制鏈接]

      2017-6-17 12:53
      zeki_10 閱讀:21971 評論:11 贊:5
      Tag:  Android 開發
      -----------------------引子-----------------------------------------        
              之前一直聽一個做IOS開發的大學同學夸夸其談他的Swift語言多么多么好,Java語言就是個渣渣。終于,在Google 2017 IO大會上,Kotlin正式被選為作為Android開發的官方語言。之前聽說了這個傳奇的語言,但是并沒有認真的去嘗試使用他用到開發中,現在已經成為官方語言了,學習是必須的了!首先看看他的一些特性吧,之前看了一些Swift語言的特點,就先拿Kotlin和Swift和Java的對比來看看他的優勢吧。       
              Kotlin和Swift、Java      
              Kotlin 是一個基于 JVM 的新的編程語言,由 JetBrains開發。       
              后來了解到Kotlin原來是以一個島的名字命名的(Котлин),它是一門靜態類型編程語言,支持JVM平臺,Android平臺,瀏覽器JS運行環境,本地機器碼等。支持與Java,Android 100% 完全互操作。
             
             (注:zkzqzzz為本人常用ID)
             Swift,蘋果于2014年WWDC(蘋果開發者大會)發布的新開發語言,可與Objective-C共同運行于Mac OS和iOS平臺,用于搭建基于蘋果平臺的應用程序。一個很不錯的語言。
             Java就不用說了,以前做Android開發那是都要把Java的基礎打牢呀!
             相信使用Kotlin用來開發的人肯定會越來越多的,這也許就是一個語言的魅力所在吧! 閑話少敘,我們還是來看干貨吧!

              一、簡單比較
                   1.Hello,APKBUS! 
                           Swift:  print("Hello,APKBUS!")
                           Kotlin: println("Hello,APKBUS!")
                           JAVA:  System.out.println("Hello,APKBUS!");
                    2.變量和常量
                           Swift:var myVariable = 42
                                           myVariable = 50
                                      let myConstant = 42
                           Kotlin:var myVariable = 42
                                            myVariable = 50
                                       val myConstant = 42   (Kotlin和Swift確實是很像喲。)
                           Java:  int  myVariable =42;
                                            myVariable =50;
                                      static final int myConstant = 42;
      感覺Swift和Kotlin都比Java要簡潔很多。 3.顯式類型 Swift : let explicitDouble: Double = 70 Kotlin : val explicitDouble: Double = 70.0 4.強制類型轉換 Swift : let label = "The width is " let width = 94 let widthLabel = label + String(width) Kotlin : val label = "The width is " val width = 94 val widthLabel = label + width 5.數組 Swift : var shoppingList = ["catfish", "water","tulips", "blue paint"] shoppingList[1] = "bottle of water" Kotlin : val shoppingList = arrayOf("catfish", "water","tulips", "blue paint") shoppingList[1] = "bottle of water" 6.函數 Swift : func greet(_ name: String,_ day: String) -> String { return "Hello \(name),today is \(day)." } greet("Bob", "Tuesday") Kotlin : fun greet(name: String, day: String): String { return "Hello $name, today is $day."} greet("Bob", "Tuesday") 7.類聲明及用法 Swift : 聲明:class Shape { var numberOfSides = 0 func simpleDescription() -> String { return "A shape with \(numberOfSides) sides." } } 用法:var shape = Shape() shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription() Kotlin : 聲明:class Shape { var numberOfSides = 0 fun simpleDescription() = "A shape with $numberOfSides sides." } 用法: var shape = Shape() shape.numberOfSides = 7 var shapeDescription = shape.simpleDescription()
      經過上面簡單的比較,發現Kotlin和Swift吼像呀!!! 當然,這兩門語言還有其他可以比較的點,大家可以自己去找下,和Java的比較沒有寫出來,大家看下這兩個的再想想Java怎么實現的就可以理解Kotlin的偉大了。
                Kotlin相比Java有很多優勢,首先一點就是你可以用更少的代碼來做更多的事,其次Kotlin居然可以幫我們來避免空指針的問題,這個問題可是很多程序猿在寫代碼時時刻警惕著卻又不能很好避免的問題呢!而且使用集合的時候也很方便,而在安卓開發中,視圖綁定是必須要做的,雖然有黃油刀的輔助可能會省了不少力,但是現在Kotlin已經可以幫你很好的解決這個問題了!(具體的大家去搜索一下吧。傳送門:Java-Kotlin
               差點跑偏了,標題可是用Kotlin來開發Android 的呢,咱們現在只是對這門語言有了個大致的了解。現在就開始用他先做個小東西吧。
              Kotlin開發Android
                開發安卓的話肯定要有個開發工具吧,我之前一直用的是Android Studio,感覺挺不錯的,后來到公司實習之后,發現公司基本上都是用的Intellij,然后我就開始用這個工具做開發了,感覺還是很好用的。我在這里使用的是Android Studio3.0 Canary版本,好像是Google在IO大會的時候更新的一個預覽版本吧。如果使用正式版本的話,可能需要安裝Kotlin的插件,但是3.0的版本就是本身集成好的,不需要安裝多余的插件。
                    這里我給大家演示的是2.3版本下使用Kotlin。
                    1.首先新建一個項目KotlinProject, 配置項目的Gradle文件
                       配置項目Gradle文件:
                         apply 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文件:
                          compile '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是JetBrains開發的一個強大的庫,說起JetBrains ,那就牛逼了,Kotlin語言是他們開發的,最流行的的開發工具intellij idea都是他們開發的,AS也是基于IDEA的。好了,言歸正傳,Anko是Kotlin官方開發的一個讓開發Android應用更快速更簡單的Kotlin庫,并且能讓我們書寫的代碼更簡單清楚更容易閱讀。(具體也可以看我一篇博客:用Kotlin和Anko實現安卓UI )
                    接下來,我們就通過代碼來理解Kotlin語言開發Android的優勢所在。
                     視圖綁定不需要findViewById
                     做過Android開發的人都知道,布局文件寫的多了,findViewById也是一個很大的工作量,而且還要先聲明變量,在findViewById然后再強轉成我們的控件,使用方式一般如下

      [代碼]java代碼:

                     TextView username;
                     username=(TextView)findViewById(R.id.user);
                     username.setText("我是來自APKBUS的文本");
                         有時候寫的是不是想吐,可能有些人說現在不是有一些注解的庫,如butterknife,當我們使用注解時可以不用findViewById了,使用方式如下

      [代碼]java代碼:

                     @BindView(R.id.user)
                     TextView username;
                     username.setText("我是來自APKBUS的文本");
                       確實是這樣,使用注解后確實給我們少了一些工作量,不過這依然沒有最簡單化,最簡單的就是我們可以直接給id為user的控件直接賦值,或許你會感覺這有點不可思議。不過Kotlin確實做到了。我們可以直接這樣寫:

      [代碼]java代碼:

                    user.text="我是來自APKBUS的文本"
                        user就是我們布局文件聲明的id,.text就想當與setText()給,在Kotlin語言中,我們看不到了像Java中的set/get方法了。需要注意的時,當我沒呢這樣使用,需要加入下面一句代碼  
                     

      [代碼]java代碼:

                //activity_login就是我們的布局
                import kotlinx.android.synthetic.main.activity_login.*     

                 Anko Layout   

                         通常我們使用xml文件寫我們的布局,但是他有一些缺點如不是類型安全,不是空安全,解析xml文件消耗更多的CPU和電量等等。而Anko Layout可以使用DSL動態創建我們的UI,并且它比我們使用Java動態創建布局方便很多主要是更簡潔,它和擁有xml創建布局的層級關系,能讓我們更容易閱讀。   
                     

      [代碼]java代碼:

              verticalLayout {
                  val textView=textView("我是來自APKBUS的文本")
      val name = editText("EditText") button("Button") { onClick { toast("${name.text}!") } } }
                      我們在OnCreate方法中可以去掉setContentView,然后加入上面代碼就可以顯示如下圖的效果,即一個垂直的線性布局中,放了一個TextView,一個EditText,和一個Button。并且Button中有一個點擊事件,當點擊時將EditText的內容
                    上面的代碼是不是很簡單易懂,當然,默認的控件并不能滿足我們的需求,例如我們會更改字體的顏色及大小,會設置寬度和高度,會設置margin,padding值,那么該如何實行呢,當然也很簡單,因為它的邏輯和xml書寫布局是一個套路。例如以下實現 
                

      [代碼]java代碼:

                  val textView=textView("我是來自APKBUS的文本"){
      textSize = sp(17).toFloat() textColor=context.resources.getColor(R.color.red) }.lparams{ margin=dip(10) height= dip(40) width= matchParent }

                 在上面創建UI過程中,我們直接把創建UI的代碼寫在onCreate方法中了,當然,還有一種寫法。我們創建一個內部類實行AnkoComponent接口,并重寫createView方法,該方法返回一個View,也就是我們創建的布局。修改如下     

      [代碼]java代碼:

        inner class UI : AnkoComponent {
              override fun createView(ui: AnkoContext): View {
                 return with(ui){
                     verticalLayout {
                         val textView=textView("我是來自APKBUS的文本"){
      textSize = sp(17).toFloat() textColor=context.resources.getColor(R.color.red) }.lparams{ margin=dip(10) height= dip(40) width= matchParent } val name = editText("EditText") button("Button") { onClick { view -> toast("Hello, ${name.text}!") } } } } } }

              然后在onCreate方法中加一句代碼,即可創建我們的布局頁面了。如下

      [代碼]java代碼:

           UI().setContentView(this@LoginActivity)

               現在我們編譯運行,發現效果和布局文件寫的界面是一樣的。但是它的性能是有優勢的,其實吧并沒有發覺性能優勢。不管怎樣,這種DSL確實便于閱讀,也很容易上手,在上面的代碼中,你可能注意到了dip(10),它表示將10dp轉換為像素的意思,是Anko的擴展函數,說的擴展函數,如果閱讀過Anko的源碼我們發現里面大量的使用擴展函數,這也是Kotlin語言的優勢之一。確實很強大,例如dip擴展(摘取View擴展)


      [代碼]java代碼:

            inline fun View.dip(value: Int): Int = context.dip(value)
            fun Context.dip(value: Int): Int = (value * resources.displayMetrics.density).toInt()

                在上面resources.displayMetrics.density和我們Java getResources().getDisplayMetrics().density是一個效果,不過看著你會不會感覺比Java書寫舒服多了,反正我是這么感覺的。在上面的我們給Button加了一個點擊事件,我們發現它支持lambda表達式。我們想顯示一個Toast,只需要toast("內容")就可以了,是不是又很簡潔。其實它也是擴展函數,實現

      [代碼]java代碼:

           inline fun AnkoContext<*>.toast(message: CharSequence) = ctx.toast(message)
           fun Context.toast(message: CharSequence) = Toast.makeText(this, message, Toast.LENGTH_SHORT).show()

              當然創建dialog依然也很簡單,如下

      [代碼]java代碼:

           alert ("我是Dialog"){
                            yesButton { toast("yes")}
                            noButton {  toast("no")}
                          }.show()


      [代碼]java代碼:

          doAsync {
                  //后臺執行代碼
                  uiThread { 
                  //UI線程
                  toast("線程${Thread.currentThread().name}") }
              }

              如果你使用Kotlin開發Android一段時間后,會發現它給我們減少了很多的代碼量,當然更多的優勢及用法需要我們自己去探索。相信經過探索后它會讓你大吃一驚。

      [代碼]xml代碼:

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:custom="http://schemas.android.com/apk/res-auto"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:fitsSystemWindows="true" >
         
          <RelativeLayout
              android:id="@+id/login_layout"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_marginLeft="20dp"
              android:layout_marginRight="20dp"
              android:gravity="center" >
              <FrameLayout
                  android:id="@+id/username_layout"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:layout_marginTop="55dp"
                  android:gravity="center" >
                  <EditText
                      android:id="@+id/username"
                      android:layout_width="fill_parent"
                      android:layout_height="@dimen/default_edittext_height"
                      android:layout_marginTop="5dp"
                      android:inputType="number"
                      android:paddingRight="60dp"
                      android:maxLength="20"
                      android:paddingLeft="55dp" >
                  </EditText>
                  <ImageView
                      android:layout_width="22dp"
                      android:layout_height="21dp"
                      android:layout_marginStart="8dp"               
                      android:layout_gravity="left|center_vertical"
                      android:background="@drawable/login_usr_in_img"
                      android:visibility="visible" />
                  <TextView
                      android:id="@+id/contry_sn"
                      android:layout_width="40dp"
                      android:layout_height="50dp"
                      android:layout_gravity="left|center_vertical"
                      android:layout_marginTop="4dp"
                      android:gravity="center"
                      android:text="+62"
                      android:textColor="@android:color/black"
                      android:textSize="18sp"
                      android:visibility="invisible" />
                  
                  <Button 
                      android:id="@+id/bt_username_clear"
                      android:layout_width="23dp"
                      android:layout_height="23dp"
                      android:background="@drawable/button_clear"
                      android:layout_gravity="right|center_vertical"
                      android:layout_marginRight="10dp"
                      android:visibility="invisible"
                      />
              </FrameLayout>
              <FrameLayout
                  android:id="@+id/usercode_layout"
                  android:layout_width="fill_parent"
                  android:layout_height="wrap_content"
                  android:layout_below="@id/username_layout"
                  android:layout_marginTop="6dp"
                  android:gravity="center" >
                  <EditText
                      android:id="@+id/password"
                      android:layout_width="fill_parent"
                      android:layout_height="@dimen/default_edittext_height"  //40
                      android:inputType="textPassword"
                      android:paddingRight="60dp"
                      android:maxLength="20"
                      android:paddingLeft="55dp" >
                  </EditText>
                  <ImageView
                      android:layout_width="24dp"
                      android:layout_height="22dp"
                      android:layout_marginStart="7dp"               
                      android:layout_gravity="left|center_vertical"
                      android:background="@drawable/login_code_in_img" />
                     <Button 
                      android:id="@+id/bt_pwd_eye"
                      android:layout_width="23dp"
                      android:layout_height="23dp"
                      android:background="@drawable/button_eye_n"
                      android:layout_gravity="right|center_vertical"
                      android:layout_marginRight="10dp"
                      />
                     <Button 
                      android:id="@+id/bt_pwd_clear"
                      android:layout_width="23dp"
                      android:layout_height="23dp"
                      android:background="@drawable/button_clear"
                      android:visibility="invisible"
                      android:layout_gravity="right|center_vertical"
                      android:layout_marginRight="33dp"
                      />
              </FrameLayout>
        
              <Button
                  android:id="@+id/login"
                  android:layout_width="fill_parent"
                  android:layout_height="@dimen/default_button_height"
                  android:layout_below="@id/usercode_layout"
                  android:layout_marginTop="30dp"
                  android:background="#ff336699"
                  android:textColor="@android:color/white"
                  
                  android:gravity="center"
                  android:text="登錄" />
              <Button
                  android:id="@+id/login_error"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_alignRight="@id/login"
                  android:layout_below="@id/login"
                  android:background="#00000000"            
                  android:text="忘記密碼"
                  android:textSize="16sp" />
              <Button
                  android:id="@+id/register"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_alignLeft="@id/login"
                  android:layout_below="@id/login"
                  android:background="#00000000"
                  android:gravity="left|center_vertical"
                  android:text="注冊"
                  android:textSize="16sp"            
                  android:visibility="visible" />
          </RelativeLayout>
          <RelativeLayout
              android:id="@+id/remember_layout000"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentBottom="true"
              android:layout_marginBottom="1dp"
              android:layout_marginLeft="20dp"
              android:layout_marginRight="20dp" >
          </RelativeLayout>
      </RelativeLayout>


      [代碼]java代碼:

      lateinit var et_account: EditText
          lateinit var et_password: EditText
          inner class LoginUi : AnkoComponent {
              override fun createView(ui: AnkoContext) = with(ui) {
                  verticalLayout {
                      backgroundColor = context.resources.getColor(android.R.color.white)
                      gravity = Gravity.CENTER_HORIZONTAL
                      imageView(R.mipmap.ic_launcher).lparams {
                          width = dip(100)
                          height = dip(100)
                          topMargin = dip(64)
                      }
      
                      linearLayout {
                          gravity = Gravity.CENTER_VERTICAL
                          orientation = HORIZONTAL
                          backgroundResource = R.drawable.bg_frame_corner
                          imageView {
                              image = resources.getDrawable(R.mipmap.ic_username)
                          }.lparams(width = wrapContent, height = wrapContent) {
                              leftMargin = dip(12)
                              rightMargin = dip(15)
                          }
                          et_account = editText {
                              hint = "登錄賬戶"
                              hintTextColor = Color.parseColor("#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 = resources.getDrawable(R.mipmap.ic_password)
                          }.lparams {
                              leftMargin = dip(12)
                              rightMargin = dip(15)
                          }
                          et_password = editText {
                              hint = "登錄密碼"
                              hintTextColor = Color.parseColor("#666666")
                              textSize = 16f
                              background = null
                          }
                      }.lparams {
                          width = dip(300)
                          height = dip(40)
                          topMargin = dip(10)
      
                      }
      
                      button("登錄") {
                          gravity = Gravity.CENTER
                          background = resources.getDrawable(R.drawable.bg_login_btn)
                          textColor = Color.parseColor("#ffffff")
                          onClick {
                              if (et_account.text.toString().isNotEmpty() && et_password.text.toString().isNotEmpty())
                                  startActivity() else toast("請輸入賬戶或者密碼")
                          }
                      }.lparams(width = dip(300), height = dip(44)) {
                          topMargin = dip(18)
                      }
                      linearLayout {
                          orientation = HORIZONTAL
                          gravity = Gravity.CENTER_VERTICAL
                          checkBox("注冊") {
                              textColor = Color.parseColor("#666666")
                              textSize = 16f
                              leftPadding = dip(5)
                          }
                          textView("忘記密碼") {
                              textColor = Color.parseColor("#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
                      }
                  }
              }
          }

             看到上面的代碼怎么樣,看起來還不錯吧,即使現在你不會寫,但是你也能讀懂它。在上面我們給登錄按鈕設置一個打開MainActivity的事件。

              startActivity的<>中寫的是我們要跳轉的Activity,如果給打開的界面傳遞參數,直接寫在()中。例如我們將輸入的賬號和密碼傳到跳轉的界面,則實現為

      [代碼]java代碼:

              startActivity("account" to et_account.text.toString(),"password" to et_password.text.toString())

                  不會用巴士的編輯器,感覺好氣啊。。不過總算是寫完了,Kotlin這門語言肯定會發展的越來越好,當然,現在還在用Java開發的也不用擔心會被拋棄,畢竟Java的用處還是很廣的。本片博文參與《安卓巴士線上博文大賽終于來了  》活動,活動鏈接安卓巴士線上博文大賽終于來了 。


      我來說兩句
      您需要登錄后才可以評論 登錄 | 立即注冊
      facelist
      所有評論(11)
      vivian00 2017-6-17 14:30
      感覺很不錯呢,謝謝分享!
      回復
      qingqingq 2017-6-17 20:09
      厲害了!贊一個
      回復
      googleer 2017-6-18 16:20
      強烈支持樓主ing……
      回復
      bennyq 2017-6-19 09:18
      很不錯,贊
      回復
      bear~ 2017-6-19 11:29
      大神你終于回來更文章了哈!
      回復
      九霄逆鱗 2017-6-19 14:33
      厲害了,贊贊贊
      回復
      James1991 2017-6-21 12:17
      樓樓可以使用Markdown編輯器編輯帖子
      回復
      zeki_10 2017-6-21 12:44
      James1991: 樓樓可以使用Markdown編輯器編輯帖子
      主要還沒有用慣。。。
      回復
      test_user 2017-8-24 11:01
      8錯
      回復
      manyuser 2018-2-25 16:45
      現在學會不會太晚了??
      回復
      freedomqian 2018-7-12 13:49
      謝謝分享 。
      回復
      領先的中文移動開發者社區
      18620764416
      7*24全天服務
      意見反饋:1294855032@qq.com

      掃一掃關注我們

      Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粵ICP備15117877號 )

      夫妻性姿势真人示范 - 视频 - 在线观看 - 影视资讯 - 唯爱网