Aaron Wu
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invitee
    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Versions and GitHub Sync Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
Invitee
Publish Note

Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

Your note will be visible on your profile and discoverable by anyone.
Your note is now live.
This note is visible on your profile and discoverable online.
Everyone on the web can find and read all notes of this public team.
See published notes
Unpublish note
Please check the box to agree to the Community Guidelines.
View profile
Engagement control
Commenting
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
  • Everyone
Suggest edit
Permission
Disabled Forbidden Owners Signed-in users Everyone
Enable
Permission
  • Forbidden
  • Owners
  • Signed-in users
Emoji Reply
Enable
Import from Dropbox Google Drive Gist Clipboard
   owned this note    owned this note      
Published Linked with GitHub
Subscribed
  • Any changes
    Be notified of any changes
  • Mention me
    Be notified of mention me
  • Unsubscribe
Subscribe
# 寒訓App講義 ## 前言 > 本講義所有的連結皆可以透過此連結點選,所有需下載的東西也在裡面: > https://bit.ly/2023WinterApp > ![](https://i.imgur.com/WgqUEyp.png =150x) ### android app 介紹 手機應用程式是最近十分熱門的一份商機,也是許多工程師必備的技能。不過以目前目前市場來說,手機app開發所使用的程式語言可以分為針對iOS的Swift語言以及針對android的Java或是Kotlin。但是,由於iOS系統的封閉性,如果要開發相關的app,只能在蘋果電腦(Mac)上使用Xcode開發;另外,開發完的app也較難直接安裝到相對應手機上。因此,這次我們主要會進行android app的開發。 ### Kotlin 語言介紹 > Kotlin官網:https://kotlinlang.org/ Kotlin 程式語言為 JetBrains 公司所開發的程式語言,是一種在Java虛擬機(JVM)上執行的靜態型別程式語言。其程式碼可以和Java在JVM當中互相相容運作,另外,也支援轉為JavaScript作為前端語言。 Kotlin在這幾年在app界十分火熱,尤其是在2017年的Google開發者大會中,Google宣布在Android上為Kotlin提供最佳支持。換句話說,Google表態希望所有開法者使用Kotlin取代Java作為app開發的主力語言。 Kotlin相對於Java的優勢: * 設計變得簡潔,並且讓語意清楚 * 避免 NullError * 容易入門 另外,Kotlin還有一個超級大優勢就是他有Google大神幫他背書,因此開發文件十分齊全,無論是新手或是Java使用者都可以很方便地轉移過來。 ### UI 介紹 User Interface(使用者介面,簡稱UI)指的是在一個App當中使用者看到的所有東西以及他的版面配置,例如文字位置、大小、顏色、圖片及按鈕等等。在Android App裡面UI都是用XML所寫的,語法上有點類似HTML和CSS的混合。不過,如果使用Android Studio來開發的話,可以用圖形化介面,也就是直接以滑鼠拖拉的方式來完成UI的設計。 ### 學習資源 學習Android基本上有兩大資源 1. 靠Google大神 * 以**Kotlin**、**Android App入門**等關鍵字搜尋,基本上可以找到許多的學習資料,有的寫的都不錯,尤其是在iT邦幫忙或Medium等平台上都有不錯的部落格文章。 > https://clay-atlas.com/blog/2021/05/07/kotlin-cn-tutorial/ > https://ithelp.ithome.com.tw/articles/10233580 2. 靠Google大神 * 前面有提到,Google 希望推動以Kotlin作為主要的App開發語言,因此他自己研發了一整套的免費教材,超推,~~甚至比看這篇講義或聽我上課有用很多倍。~~ > https://developer.android.com/courses/android-basics-kotlin/course ### Android Studio Android Studio 是由 Google 和 JetBrains 公司合作的IDE,也是 Google 官方推薦使用的IDE。Android Studio 功能十分強大,甚至可以直接在電腦中弄出一台虛擬的 Android 手機出來方便我們進行 app 的測試。所以,我們先來安裝它吧! ### Android Studio 基本教學 Google教學,建議可以直接按照其步驟完成:https://developer.android.com/courses/pathways/android-basics-kotlin-two 1. 下載安裝檔 - Link: https://developer.android.com/studio 2. 安裝完之後長相 ![](https://i.imgur.com/8ZQjLoD.png) 3. 建立第一個專案:按 New Project ![](https://i.imgur.com/rJQvzkp.png) 4. 選擇 empty activity ![](https://i.imgur.com/qVVvSy5.png) 5. 按一下視窗底部的「Next」(下一步)。「New Project」(新增專案) 對話方塊隨即開啟。 ![](https://i.imgur.com/VH0ling.png) 以下針對以上進行講解: * 「Name」(名稱) 是應用程式的名稱。 * 「Package name」(套件名稱) 是 Android 系統用來識別應用程式的名稱。通常,此欄位會預設使用貴機構的名稱,後面加上應用程式的名稱,且全部使用小寫。 * 「Save location」(儲存位置) 是儲存所有專案相關檔案的地方。請記下這些檔案在電腦的位置,以便尋找檔案。你也可以暫時將儲存位置保持原樣。 * 「Language」(語言) 定義了專案要使用的程式設計語言。選「Kotlin」。 * 「Minimum SDK」(SDK 最低版本) 代表可執行應用程式的 Android 最低版本。請從下拉式清單選取 API 19: Android 4.4 (KitKat)。 6. 第一次開啟 Android Studio 時,您會看到三個視窗: ![](https://i.imgur.com/fdzABfw.png) (1)「Project」(專案) 視窗會顯示專案的檔案和資料夾。 (2)「Editing」(編輯) 視窗可編輯程式碼。 (3)「What's New」(最新消息) 7. 建立手機模擬器 https://bit.ly/3PKmweK 直接看這教學連結了吧,不過,手機請選擇 Pixel6。 ![](https://i.imgur.com/wTv4tBl.png) 找不到Device Manager」的人,它在 Android Studio 的選單列中,請依序選取「Tools」(工具) > 「Device Manager」(裝置管理工具)。 ![](https://i.imgur.com/tNa964K.png) 8. Android Studio 檔案結構介紹 ![](https://i.imgur.com/6jJcf5k.png) 在res資料夾中,會有一些像是圖片、版面配置、UI等等的東東。 而程式碼則都在app資料夾當中。 ## Kotlin 語法教學 Kotlin語法十分簡單好上手,網路上資源也相當的多,如果想要自學的話推薦項Google大神求助或是照Google大神的教學包來學習。 另外,這篇文章寫得也不錯:https://clay-atlas.com/blog/2021/05/07/kotlin-cn-tutorial/ 基本上,Kotlin除了可以用在App上面,也可以像python或C++一樣直接拿來寫一般的程式,安裝Kotlin環境的方式就不在此贅述了,有興趣的可以自己上網搜尋;基本上,安裝Android Studio時Kotlin環境就已經會安裝完成了。 不過,學語法就直接用IDE來跑,其實有點可怕。因此,我們可以先用一些稱為 Kotlin Playground 的線上編輯器作為測試。 > Kotlin Playground (provided by Google) > https://developer.android.com/training/kotlinplayground > Kotlin Playground (provided by kotlinlang.org) > https://play.kotlinlang.org/ ![](https://i.imgur.com/vk3eNZz.png)(應該不用一個一個講功能了吧w) 以下開始正式介紹Kotlin的語法。 ### Hello World ```kotlin= fun main() { println("Hello, world!!!") } ``` 這是一個Kotlin的 Hello World 程式碼,我們可以看到幾個重點: 1. 可以不加分號 2. 用fun關鍵字宣告函數 3. 和C++一樣要有main函數 4. 用`println()`輸出並且換行 5. 可以改用`print()`,就不會自動換行 ### 變數 #### 變數型態 https://kotlinlang.org/docs/basic-types.html 注意事項:Kotlin所有變數類別**首字母皆大寫** * 整數類別:(做講義的幫我轉表格感謝) ![](https://i.imgur.com/onkZd2A.png) * 浮點數型態(由大到小): `Double`, `Float` * 字元型態:`Char` * 布林值型態:`Boolean` * 字串:`String` #### 變數宣告 Kotlin提供兩種變數,分別為`val`和`var` * `val`代表value,代表此變數只讀不寫(除了初始化不能用`=`符號) * `var`代表variable,就是一般的變數。 變數的宣告方式如下: `var 或 val 關鍵字` `變數名稱` `:` `型態` `=` `初始值` 例如: ```kotlin= val a: Int = 10 var b: String = "I am so weak." val c: Float = 1.0 + 3.0 ``` 有初始化的變數也可以省略`型態`部分,這時會很像JS的變數宣告,例如: ```kotlin= var a = 10 ``` 補充:要注意的是kotlin裡面也有`const`關鍵字,用來宣告常數。 ### 輸入 Kotlin的輸入較少使用,這邊只是做個補充。 使用 `readLine()`可以讀取一整行成字串,但若要像C++的cin一樣,可以使用 `import java.util.Scanner` 例如以下獲取整數輸入的範例 ```kotlin= import java.util.Scanner fun main() { val read = Scanner(System.in) println("請輸入你的年齡:") var age = read.nextInt() println("你的年齡是:"+age) } ``` ### 條件 > https://ithelp.ithome.com.tw/articles/10194336 有 `if` 和` when` 兩種用法。 基本的if用法和C++一致: ```kotlin= val count = 10 if (count < 5) { println("太少") } else if (count > 5) { println("太多") } else { println("剛剛好") } ``` 神奇的是,Kotlin中的if可以有回傳值。每個區段的最後一行的值,會被當作若執行到該區段會讓整個語句回傳的值: ```kotlin= var score: Int = 85 var grade: String = if(score<=100 && score>80){ "A" }else if(score<=80 && score>=60){ "B" }else{ "C" } println("Grade: $grade") //印出 Grade: A ``` `when`有點類似`switch-case`: ```kotlin= when{ 條件一 -> { //如果條件一成立就執行區塊,反之繼續判斷條件二 } 條件二 -> { //如果條件二成立就執行區塊,反之繼續判斷條件三,以此類推 } else -> { //如果以上的條件都不符合,就執行這個區塊 } } ``` 範例: ```kotlin= var score: Int = 85 var grade = "" when{ score<=100 && score>80 -> grade = "A" score<=80 && score>=60 -> grade = "B" else -> grade = "C" } ``` ```kotlin= var score: Int = 85 var grade: String = when{ score<=100 && score>80 -> "A" score<=80 && score>=60 -> "B" else -> "C" } ``` ### 迴圈 很簡單,自己看: ```kotlin= // for (節錄自 Kotlin 官方教學程式碼) val names = listOf("Anne", "Peter", "Jeff") // 會接續印出 Anne 、 Peter 、 Jeff for (name in names) { println(name) } // 會接續印出 0 到 10 for (x in 0..10) println(x) // 會接續印出 0 到 9 for (x in 0 until 10) println(x) // 會接續印出 0, 2, 4, 6, 8 for (x in 0 until 10 step 2) println(x) // 會接續印出 10, 8, 6, 4, 2, 0 for (x in 10 downTo 0 step 2) println(x) // 會接續印出 0: Anne, 1: Peter, 2: Jeff for ((index, value) in names.withIndex()) { println("$index: $value") } // while (節錄自 Kotlin 官方教學程式碼) // 會接續印出 0 到 9 var x = 0 while (x < 10) { println(x) x++ } // 標籤型的 continue 和 break 用於跳出外層迴圈 (節錄自 Kotlin 官方教學程式碼) outer@ for (n in 2..100) { for (d in 2 until n) { if (n % d == 0) continue@outer } println("$n is prime") } ``` ###### (source: https://ithelp.ithome.com.tw/articles/10233580) 可以看到 `(1..10)`為range語句,會產生一個1~10的range。 ### 亂數 https://andyludeveloper.medium.com/kotlin-%E5%B0%8F%E6%92%87%E6%AD%A5-8-%E5%9B%9B%E5%80%8B%E7%94%A2%E7%94%9F%E9%9A%A8%E6%A9%9F%E6%95%B8%E5%AD%97%E7%9A%84%E6%96%B9%E6%B3%95-5fa905be5981 ```kotlin= Random.nextInt() // 產生一個Int亂數 Random.nextFloat() // 產生一個Float亂數 Random.nextInt(1, 10) // 產生一個1到10的亂數 (1..10).random() // 產生一個1到10的亂數 ``` ### 函數 定義方式: ```kotlin fun [函式名稱]([參數 1 名稱]: [參數 1 型態]): [回傳型態] { [內容] } ``` 範例: ```kotlin= fun BMI(val w: Float, val h: Float): Float { retunr w/(h*h); } // 如果函式只有一行 return 的話,可簡寫成等式 fun happyBirthday2(name: String, age: Int) = "Happy ${age}th birthday, $name!" ``` ### class 建議直接看這一篇教學,這裡礙於版面與教學時間限制將不詳述。 > 在 Kotlin 中使用類別和物件 https://developer.android.com/codelabs/basic-android-kotlin-compose-classes-and-objects?hl=zh-tw#0 ### collection 類似C++的STL,包含Array、List、Set、Map等等。詳細列表如下: ![](https://i.imgur.com/YinSrcg.png) > 張成家我直接幫你把上面表格打成Latex原始碼了 ``` \begin{table}[] \begin{tabular}{llll} 名稱 & 中文名稱 & 備註 & 教學網址 \\ Array & 陣列 & 長度固定 & https://ithelp.ithome.com.tw/articles/10237401 \\ List & 清單 & 長度\&內容不可變 & https://ithelp.ithome.com.tw/articles/10238930 \\ MutableList & 可變清單 & 長度\&內容可變 & \\ Set & 集合 & 內容不可變、內容不重複 & https://ithelp.ithome.com.tw/articles/10239409 \\ MutableSet & 可變集合 & 內容可變、內容不重複 & \\ Map & 就是Map & 鍵(Key)值(Value)對照 & https://ithelp.ithome.com.tw/articles/10240148 \\ MutableMap & 就是可變Map & 內容可變 & \end{tabular} \end{table} ``` 今天會用到的只有MutableSet,Set和MutableSet是一個按照加入順序進行排列、沒有重複值的集合。今天會用到的語法如下: #### 宣告 用`mutableSetOf()`函數: ```kotlin= val muSet = mutableSetOf("Jim", "Sue", "Sue", "Nick", "Nick") // 只會存放不重複的 Jim, Sue, Nick val SetOfAges: MutableSet<int> = mutableSetOf(31, 25, 10, 32, 12) ``` 若要宣告空的: ```kotlin= val emptyMutableSet = mutableSetOf<String>() ``` #### 取值、亂數取值 ```kotlin= muSet.elementAt(0) // "tim" println(muSet.random()) // 亂數輸出一個 var returnValue = muSet.randomOrNull() // set沒東西時會回傳null ``` #### 取大小&修改&刪除 ```kotlin= // 印出 set 大小 println(muSet.size) // 在 set 最後面加入 muSet.add("Bob") // 在 set 最後面加入一堆 data muSet.addAll(listOf("a", "b", "c")) // remove 某資料 muSet.remove("tim") // 清除所有 muSet.clear() ``` ## UI 基礎教學 應用程式的使用者介面 (UI),是指畫面上顯示的文字、圖片、按鈕及其他多種元素。它不僅是應用程式向使用者顯示內容的方式,也是使用者與應用程式互動的方式。 這些元素每個都是所謂的 View。您在應用程式畫面上看到的內容幾乎都是 View。Views 可以是互動元素,例如可點擊的按鈕或可編輯的輸入欄位。 ### 版面配置編輯器 這裡是Android對於新手最友善的一個功能了。只需要透過拖拉即可將東西放到相對應的位置。 從左邊專案資料夾中選擇 res/layout/activity_main.xml 即可編輯預設的版面配置。 在app當中,UI都是使用xml檔案進行記錄的。 如果打開activity_main.xml之後沒有看到版面配置編輯器,可在右上角找到這個地方 ![](https://i.imgur.com/mhONZEO.png) 請選擇Design 版面配置編輯器的截圖長相: ![](https://i.imgur.com/xC9NFMd.png) * 左側標記 (1) 的地方是「Project」(專案) 視窗 * 畫面中央會顯示 (4) 和 (5) 兩個繪圖,分別代表應用程式的螢幕版面配置。 * 左側標記 (4)為「Design」(設計) 檢視畫面,會顯示應用程式執行時呈現的近似效果。 * 右側標記 (5) 的視窗代表「Blueprint」(藍圖) 檢視畫面 * 標記 (2) 的「Palette」(區塊面板) 視窗有各種你可以使用的views * 標記 (3) 的「Component Tree」(元件樹狀結構) 是另一種螢幕檢視畫面方式,列出螢幕的所有檢視畫面。 * 右邊(6)視窗是「屬性」(Attributes),顯示了 View 的各種設定,可在這裡加以變更。 ### 今天會用的View: ![](https://i.imgur.com/m1IolyI.png =300x) * TextView 文字方塊 * Button 按鈕 * ImageView 圖片 * EditText 輸入方塊(位在Text選單的plain text) ### View怎麼用: #### 1. 拖到畫面中 * 就,拖過去 #### 2. 固定位置 * 以我們隨邊拖移一個按鈕和一個TextView為例,你可以看到當我們選取物件時,四邊上會有四個圓圈圈。你可以將這四個箭頭拉出去,接到牆上或是其他物件上,這樣會產生彈簧樣子的圖案,代表你靠了這些彈簧定義了物件的相對位置限制。 * ![](https://i.imgur.com/2MVMICj.png) #### 3. 調整設定 點選一個物件之後,你可以在右邊的attribute視窗當中,調整這個物件的一些相關事務及設定。 ![](https://i.imgur.com/I99bgPs.png =200x) TextView 常用的設定如下: * id: 就是id,每一個物件都應該有一個專屬好認的id,請用容易記得與分辨的名字,因為等等寫程式時會使用id來分辨物件 * text: 顯示的字 * visibility: 顯示與不顯示 * layout_width 和 layout_height: 寬度及高度,wrap_content代表根據內容大小自動調整。 * textSize: 文字大小 * textColor: 文字顏色 * fontFamily: 字型 * textStyle: 樣式(粗體之類的) * textAlignment: 對齊方式 另外,如果有設定的旁邊有扳手的圖案![](https://i.imgur.com/M49nA7y.png =x20),代表此項設定是給開發者看的,實際模擬器在跑時看不到。例如,以下設定方式可以讓你在android studio裡面看到這個物件,但是實際執行app時使用者看不到。 ![](https://i.imgur.com/VEfrjGx.png) 另外,這個區域可以針對剛剛彈簧做進一步設定: ![](https://i.imgur.com/i82Z7mP.png =250x) 修改其數值代表最少該側我要留多少空間,為0則代表允許緊貼。 > ![](https://i.imgur.com/mNkIhcF.png) > 修改為60,25時的長相 其他種類views的設定也都大同小異,~~基本上和用ppt很像~~,多摸索幾次就會了。 ### Button的使用 Button基本上就是按鈕,可以按下去的那種(廢話)。 使用方式和TextView大同小異。 ### imageView的使用 ImageView為UI當中要使用圖片所用的view。在android studio中,要使用圖片必須經過兩個步驟。 #### 1. 將圖片匯入為drawable 首先,請到這裡下載今天會用到的所有圖片:https://bit.ly/2023WinterApp 接下來,點選resource manager ![](https://i.imgur.com/s1Z9KQP.png =200x) 加號,然後import drawable。在Android裡面,drawable指的是可以被畫到螢幕上的東西,包含圖片檔。 ![](https://i.imgur.com/7oQkBlA.png =300x) 接下來選擇你要上傳的圖片檔,然後按下next,就完成上傳了。 ![](https://i.imgur.com/nYrGPzj.png) ![](https://i.imgur.com/izkdMiY.png) 現在,你可以在 res > drawable資料夾中看到你上傳的檔案了 ![](https://i.imgur.com/Mm7MNPe.jpg) #### 2. 建立imageView 回到版面配置編輯器,從左邊工具箱中選擇ImageView,並拖到畫面中。 這時會跳出這個視窗: ![](https://i.imgur.com/a33oMq9.png) 從左側選擇你要用的圖片,就會建立該imageView ### editText的使用 > ![](https://i.imgur.com/RILrkIg.png =250x) > palette中的Text標籤下,除了TextView以外都是不同種的EditText,不過今天只會用到Plain Text editText基本上和textView用法差不多,但是,他設定多了一個hint選項,代表使用者尚未輸入內容時會顯示的文字。 而text屬性則為使用者輸入以及可以編輯的文字。 > editText在模擬器中長相: ![](https://i.imgur.com/xqCrMMG.png =x400) ![](https://i.imgur.com/hJxujtp.png =x400) ### xml檔案 剛剛有說過,實際上的UI是使用XML檔案紀錄的。XML是一種標記語言,語法上類似css。 ![](https://i.imgur.com/mhONZEO.png) 我們透過以上切換到code,可以看到如以下之長相。我們可以發覺,所有我們動過的屬性設定皆會被以文字方式記錄下來。 ![](https://i.imgur.com/mBoMvVX.png =x500) 切換到split標籤的話我們可以同時看到程式碼與UI的預覽。 ![](https://i.imgur.com/TK1Yf8r.png) 你可以嘗試從XML檔案直接修改Button的text屬性,你就會發覺按鈕上顯示的文字被你修改了。 ## UI 和 Kotlin 的整合 現在我們已經會使用Kotlin以及UI了,我們可以嘗試將兩者整合起來,以完成我們的app。 首先,我們可以從檔案夾中找到 MainActivity.kt 這個檔案(位於 app/java/com.example.application_name中)。這個檔案就是我們app會執行的主程式。 我們可以看到,Android studio已經幫我們寫好預設的模板了。 其中 onCreate函數就是app會自動執行的main函數。 ![](https://i.imgur.com/P6tTnQf.png) ### 開啟自動import功能 在我們用撰寫app程式碼時,常常會要用到許多的函式庫。這時,若開啟android studio的自動import功能便會方便許多。 https://www.geeksforgeeks.org/what-is-the-shortcut-to-auto-import-all-in-android-studio/ Step 1: 點選File > Settings ![](https://i.imgur.com/cXeKkJ2.png =250x) Step 2: 點選 Editor > General > Auto Import 把Insert imports on paste改成Always ![](https://i.imgur.com/0qQ3s6g.png) Step 3: 把java和kotlin的Add unambiguous imports on the fly打勾 ![](https://i.imgur.com/VM6VpPT.png) ### Toast.makeText() 原本Kotlin的輸出只會顯示在終端機當中,並不會讓使用者在app當中看到。因此,我們可以使用toast來在手機當中跳出提示訊息。 常用語法如下: ```kotlin= Toast.makeText(this, "要顯示的訊息", Toast.LENGTH_SHORT).show() ``` 如此一來,便會在螢幕下方出現一個短暫跳出的通知 ![](https://i.imgur.com/ZwjJUP9.png =x500) 如果想要學習更多toast的使用方式,可以看這一篇: https://learnexp.tw/%E3%80%90android%E3%80%91toast-%E5%BF%AB%E9%A1%AF%E5%85%83%E4%BB%B6/ ### findViewById 這個函數是將程式碼與UI整合過程中最重要的一步。 使用方式如下: ```kotlin= val 變數名: View類別 = findViewById(R.id.物件的id) ``` 這時,你會得到一個指向UI物件的一個參考變數。 舉例,如果你的UI裡面有一個id為my_button的按鈕,那麼你可以這樣寫: ```kotlin= val a: Button = findViewById(R.id.my_button) ``` 這樣一來變數a就會是那個按鈕了。如此一來,你可以透過變數a來存取my_button的屬性。使用方法為`a.屬性名` 例如如果你要輸出Button上面寫的字(text屬性),你可以這樣做: ```kotlin= val textString: String = a.text.toString() Toast.makeText(this, textString, Toast.LENGTH_SHORT).show() ``` 這一個使用方式尤其在editText上面很好用,因為使用者輸入的數字就會存在editText的text屬性裡面。透過此做法,你就可以讀取使用者輸入的內容了。 ### .setText() 如果你要更改一個textView或是editText的文字,可以使用此函數。 使用方式如下: ```kotlin= val k: TextView = findViewById(R.id.textViewid); k.setText("hello CKEFGISC") ``` ![](https://i.imgur.com/I3rLQ4N.png =x400) ------> ![](https://i.imgur.com/agGjQpK.png =x400) ### setOnClickListener 這個函數主要和按鈕連用,代表當一個按鈕被按下時,要執行什麼程式。 使用方式如下: ```kotlin= 按鈕變數.setOnClickListener{ // 這裡寫被按下之後要執行的東西 } ``` 使用例子: ```kotlin= class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val myButton: Button = findViewById(R.id.ButtonId1) myButton.setOnClickListener{ // 這裡寫被按下之後要執行的東西 Toast.makeText(this, "hahahahaha", Toast.LENGTH_SHORT).show() } } } ``` ### handler 簡單來說,就是時間暫停器。在使用app時我們有時候希望某個東西等另一段程式先執行完之後再執行,或是希望等待個秒鐘,就可以用handler。 ```kotlin= val handler = Handler() // 建立handler() handler.postDelayed( { // 計時器 // 一段時間之後要做的事 }, delayTime) // delayTime單位是毫秒 ``` ## 實作 今天我們的實作目標是做出一個真心話大冒險的app。這個app要有兩個功能: 1. 有一個旋轉的指針,當按下start按鈕之後,能夠有旋轉指針的動畫,並且停下來後會隨機出現題目 2. 有一個輸入欄和一個按鈕,輸入完之後可以將使用者輸入的問題存入問題清單中,並且在之後顯示。 ### 建立專案 請先開啟一個全新的Empty Activity專案,取名為Truth_or_Dare。 建立之後,你可以到 `res/values/strings.xml` 檔案中修改app名稱。 ![](https://i.imgur.com/becIIAZ.png) 這個檔案主要儲存所有app裡面用到的字串變數。例如先TextView我們都是直接打字串內容,但是一般來說正規做法是在這裡建立字串變數之後,再使用`R.string.變數名`來呼叫。~~但今天先別理他~~ ### 建立UI 大致上的UI長相如下(紅字是我取的ID) 指針圖片可以到雲端載點下載。 ![](https://i.imgur.com/rIvOflh.png) ### 撰寫程式碼 基本程式的架構如下: ```kotlin= package com.example.truth_or_dare import android.os.Bundle import android.view.animation.RotateAnimation import android.widget.* import androidx.appcompat.app.AppCompatActivity import android.os.Handler override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 取得各個UI元件 val rollButton: Button = findViewById(R.id.start_button) val addQuestionButton: Button = findViewById(R.id.add_button) val questionTextBlock: TextView = findViewById(R.id.question) val inputTextBlock: EditText = findViewById(R.id.text_input) val rotateArrowImage : ImageView = findViewById(R.id.spinnerImage) val questionSet: MutableSet<String> = mutableSetOf<String>( "測試問題一", "測試問題二" ) // app題目清單 rollButton.setOnClickListener { // 開始轉動按鈕被按下之後要執行的程式 } addQuestionButton.setOnClickListener { // 新增問題按鈕被按下之後要執行的程式 } } ``` ### 轉動動畫的程式碼 轉動動畫可以使用kotlin內建的Animation完成,使用方法如下 ```kotlin= val am = RotateAnimation(開始角度, 結束角度, RotateAnimation.RELATIVE_TO_SELF, 旋轉x座標中心, RotateAnimation.RELATIVE_TO_SELF, 旋轉y座標中心) // 建立動畫物件,注意,角度要用Float型態 am.duration = 旋轉時間 // 設定旋轉時間 am.setFillAfter(true) // 設定旋轉完後停在該角度 myImageView.startAnimation(am) // 將myImageView以am動畫執行 ``` 以下是一個實作範例: ```kotlin= val am = RotateAnimation(0.0F, 720.0F, RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F) // 從0度到720度,共轉兩圈 // 轉動中心在圖片的(50%, 50%)位置,即原本圖片的中心 am.duration = 2000 am.setFillAfter(true) rotateArrowImage.startAnimation(am) ``` ### 完整功能1實作程式碼 ```kotlin= var startDegree = 0.0f // 記錄目前指針的角度 var endDeg = 0.0f rollButton.setOnClickListener { // 跳出提示訊息 Toast.makeText(this, "開始旋轉!", Toast.LENGTH_SHORT).show() // 旋轉動畫 var rotateDeg : Int = (1..360).random() // 要旋轉幾度 rotateDeg += (3..6).random() * 360 // 多加幾圈提高動畫效果 endDeg = startDegree + rotateDeg; // 結束的角度為當前角度加上要旋轉的角度 val am = RotateAnimation(startDegree, endDeg, RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F) val spinTime : Long= (rotateDeg*3).toLong() // 轉多久 am.duration = spinTime am.setFillAfter(true) rotateArrowImage.startAnimation(am) startDegree = endDeg % 360 // 更新起始角度數值 val handler = Handler() // 建立handler() handler.postDelayed( { // 計時器 // 出現提問 var chosenQuestion = questionSet.random() while (chosenQuestion == questionTextBlock.text) { // 避免問題和上一題重複 chosenQuestion = questionSet.random() } questionTextBlock.setText(chosenQuestion) }, spinTime) } ``` ### 完整功能2實作程式碼 ```kotlin= addQuestionButton.setOnClickListener { val stringInTextField = inputTextBlock.text.toString() if (stringInTextField.isNotEmpty()) { questionSet.add(stringInTextField) Toast.makeText(this, "成功新增問題", Toast.LENGTH_SHORT).show() } else { Toast.makeText(this, "請先輸入內容", Toast.LENGTH_SHORT).show() } inputTextBlock.setText("") // 清空文字輸入欄 } ``` ### 完整答案: 本次app完整專案已經放置在Github上面 可以透過雲端載點:https://bit.ly/2023WinterApp 中的Link文件,或直接點選以下連結取得。 [專案連結](https://github.com/AaronWu-train/Truth_or_Dare) [MainActivity.kt (Kotlin程式碼)](https://github.com/AaronWu-train/Truth_or_Dare/blob/main/app/src/main/java/com/example/truth_or_dare/MainActivity.kt ) [activity_main.xml (UI)](https://github.com/AaronWu-train/Truth_or_Dare/blob/main/app/src/main/res/layout/activity_main.xml ) ## 建立apk檔案 製作app的最後一步,便是建立真正的安裝檔,並且安裝在自己的手機上! apk檔案為android的安裝檔格式,Android App內建支援非常簡單的方式建立apk檔。 只要在工具列點選Build -> Build Bundle(s) / APK(s) -> Build APK(s), apk檔案就編譯完成了! ![](https://i.imgur.com/81hDls1.png =300x) 完成後,右下角會跳出一則訊息,點選Locate,電腦便會從檔案總管顯示該檔案。或是可以自己到以下路徑尋找:`專案資料夾/app/build/outputs/apk/debug` ![](https://i.imgur.com/RX4Det5.png =x50) ![](https://i.imgur.com/xZcaZs7.png =x200) 接下來,你只要用任何你想得到的方式(Discord、Line、雲端)將該檔案從電腦傳送到你的手機當中,就可以安裝完成了! ## 結語 以上就是這一次寒訓app課程的全部了,希望大家都學會建立自己的app了。 另外,講師寫的app安裝檔也已經放到雲端載點了,大家也可以自行上去下載。 有其他問題的話都歡迎詢問AaW喔!

Import from clipboard

Paste your markdown or webpage here...

Advanced permission required

Your current role can only read. Ask the system administrator to acquire write and comment permission.

This team is disabled

Sorry, this team is disabled. You can't edit this note.

This note is locked

Sorry, only owner can edit this note.

Reach the limit

Sorry, you've reached the max length this note can be.
Please reduce the content or divide it to more notes, thank you!

Import from Gist

Import from Snippet

or

Export to Snippet

Are you sure?

Do you really want to delete this note?
All users will lose their connection.

Create a note from template

Create a note from template

Oops...
This template has been removed or transferred.
Upgrade
All
  • All
  • Team
No template.

Create a template

Upgrade

Delete template

Do you really want to delete this template?
Turn this template into a regular note and keep its content, versions, and comments.

This page need refresh

You have an incompatible client version.
Refresh to update.
New version available!
See releases notes here
Refresh to enjoy new features.
Your user state has changed.
Refresh to load new user state.

Sign in

Forgot password

or

By clicking below, you agree to our terms of service.

Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
Wallet ( )
Connect another wallet

New to HackMD? Sign up

Help

  • English
  • 中文
  • Français
  • Deutsch
  • 日本語
  • Español
  • Català
  • Ελληνικά
  • Português
  • italiano
  • Türkçe
  • Русский
  • Nederlands
  • hrvatski jezik
  • język polski
  • Українська
  • हिन्दी
  • svenska
  • Esperanto
  • dansk

Documents

Help & Tutorial

How to use Book mode

Slide Example

API Docs

Edit in VSCode

Install browser extension

Contacts

Feedback

Discord

Send us email

Resources

Releases

Pricing

Blog

Policy

Terms

Privacy

Cheatsheet

Syntax Example Reference
# Header Header 基本排版
- Unordered List
  • Unordered List
1. Ordered List
  1. Ordered List
- [ ] Todo List
  • Todo List
> Blockquote
Blockquote
**Bold font** Bold font
*Italics font* Italics font
~~Strikethrough~~ Strikethrough
19^th^ 19th
H~2~O H2O
++Inserted text++ Inserted text
==Marked text== Marked text
[link text](https:// "title") Link
![image alt](https:// "title") Image
`Code` Code 在筆記中貼入程式碼
```javascript
var i = 0;
```
var i = 0;
:smile: :smile: Emoji list
{%youtube youtube_id %} Externals
$L^aT_eX$ LaTeX
:::info
This is a alert area.
:::

This is a alert area.

Versions and GitHub Sync
Get Full History Access

  • Edit version name
  • Delete

revision author avatar     named on  

More Less

Note content is identical to the latest version.
Compare
    Choose a version
    No search result
    Version not found
Sign in to link this note to GitHub
Learn more
This note is not linked with GitHub
 

Feedback

Submission failed, please try again

Thanks for your support.

On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

Please give us some advice and help us improve HackMD.

 

Thanks for your feedback

Remove version name

Do you want to remove this version name and description?

Transfer ownership

Transfer to
    Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

      Link with GitHub

      Please authorize HackMD on GitHub
      • Please sign in to GitHub and install the HackMD app on your GitHub repo.
      • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
      Learn more  Sign in to GitHub

      Push the note to GitHub Push to GitHub Pull a file from GitHub

        Authorize again
       

      Choose which file to push to

      Select repo
      Refresh Authorize more repos
      Select branch
      Select file
      Select branch
      Choose version(s) to push
      • Save a new version and push
      • Choose from existing versions
      Include title and tags
      Available push count

      Pull from GitHub

       
      File from GitHub
      File from HackMD

      GitHub Link Settings

      File linked

      Linked by
      File path
      Last synced branch
      Available push count

      Danger Zone

      Unlink
      You will no longer receive notification when GitHub file changes after unlink.

      Syncing

      Push failed

      Push successfully