# 04/22 Android教學 ## Android 專案介紹 ### 建立專案 1. Create New Project ![](https://i.imgur.com/CfoH6eN.png =600x) 2. Template 選擇 Empty Activity ![](https://i.imgur.com/6cXkJiH.png =600x) 3. 命名為 BMI calculator, 語言選擇 kotlin ![](https://i.imgur.com/vjurNG5.png =600x) :::warning 注意:heavy_exclamation_mark: Minimum SDK 表示最低兼容版本 選擇的版本如果太新, 則app很有可能無法在其他裝置上運行!! ::: 4. 那就開始我們的kotlin吧~~ ![](https://i.imgur.com/7MdceMC.png =600x) --- ## 組織方式 通常以Android專案方式瀏覽專案 ![](https://i.imgur.com/3Dis0zz.png =200x) ### 專案結構 ![](https://i.imgur.com/AZlRmIi.png =400x) * manifest : 存放Android APP 的主要程式檔 * java : 存放專案主要的kotlin程式碼 * res : 存放專案不是程式碼的資源檔案, 例如:使用者UI(Layout)、圖片、文字等等。 #### AndroidManifest.xml 每個Android APP 都會有此檔案, 存放APP的基本資訊(icon、label等)、有哪些 Activity、 Service、 需要用到的權限等等。 ![](https://i.imgur.com/NrJv2Ie.png =500x) #### MainActivity.kt 寫 UI 的 Android APP 一開始會執行的地方, 一開始只有 onCreate() 方法, 載入對應的 Layout。 ![](https://i.imgur.com/PgykO9O.png =500x) **專案程式碼** ~~也就是主要戰場~~ 寫 UI 的 Android APP 一開始會執行的地方,一開始只有 `onCreate()` 方法,載入對應的 Layout。 ```kotlin= package com.example.bmicalculator import androidx.appcompat.app.AppCompatActivity import android.os.Bundle class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //這邊載入了 activity_main 的 Layout } } ``` ##### lifecycle ![](https://i.imgur.com/4Te7hS6.png =500x) 1. 當Activity準備要產生時,先呼叫onCreate方法。 2. Activity產生後(還未出現在手機螢幕上),呼叫onStart方法。 3. 當Activity出現手機上後,呼叫onResume方法。 4. 當使用者按下返回鍵結束Activity時, 先呼叫onPause方法。 5. 當Activity從螢幕上消失時,呼叫onStop方法。 6. 最後完全結束Activity之前,呼叫onDestroy方法。 :point_right: [官方參考](https://developer.android.com/guide/components/activities/activity-lifecycle) #### activity_main.xml MainActivity 的介面 Layout 檔案, 可透過圖形化介面編輯器或是直接編輯 XML 方式操作。 ![](https://i.imgur.com/aZoPckG.png =600x) 1. 調色盤:可拉取需要的元件到 UI 上。 2. 元件樹:顯示元件之間的結構。 3. 設計編輯器:分別在設計(左)和藍圖(右)視角編輯 Layout。前者為App在裝置上面的呈現, 後者為編輯界面。 4. 屬性:可以修改、查看你選擇的元件的屬性。 5. 觀看模式:可切換使用圖形化介面或 XML 編輯等。 --- ## BMI 計算器實作 ### 版面配置 切換至 activity_main.xml,並使用 XML 編輯模式。 ![](https://i.imgur.com/gSdnv1p.png =600x) #### 參考範例 ```kotli= <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <EditText android:id="@+id/input_height" android:layout_width="172dp" android:layout_height="54dp" android:layout_marginStart="176dp" android:layout_marginLeft="176dp" android:layout_marginTop="96dp" android:ems="10" android:inputType="textPersonName" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/Weight" android:layout_width="94dp" android:layout_height="43dp" android:layout_marginStart="56dp" android:layout_marginLeft="56dp" android:layout_marginTop="260dp" android:clickable="false" android:text="Weight:" android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textIsSelectable="false" android:textSize="24sp" app:autoSizeTextType="uniform" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/Height" android:layout_width="94dp" android:layout_height="43dp" android:layout_marginStart="56dp" android:layout_marginLeft="56dp" android:layout_marginTop="104dp" android:clickable="false" android:text="Height:" android:textAppearance="@style/TextAppearance.AppCompat.Body2" android:textSize="24sp" app:autoSizeTextType="uniform" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <EditText android:id="@+id/input_weight" android:layout_width="172dp" android:layout_height="54dp" android:layout_marginStart="176dp" android:layout_marginLeft="176dp" android:layout_marginTop="244dp" android:ems="10" android:inputType="textPersonName" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout> ``` #### Layout * `LinearLayout`:以縱向或橫向呈現。 * `RelativeLayout`:以相對位置呈現。 * `ConstraintLayout`:RelativeLayout 的延伸,透過物件自已本身與其它物件之間的約束來決定它的位置。 #### margin * `android:layout_margin`:本元件離上下左右各元件的外邊距。 * `android:layout_marginStart`:本元件離開始的位置的外邊距。 * `android:layout_marginEnd`:本元件離結束位置的外邊距。 * `android:layout_marginBottom`:本元件離下部元件的外邊距。 * `android:layout_marginTop`:本元件離上部元件的外邊距。 * `android:layout_marginLeft`:本元件離左部元件的外邊距。 * `android:layout_marginRight`:本元件離右部元件的外邊距。 ![](https://i.imgur.com/UMgaldK.png =300x) #### 當然也可以自己拉拉看版面~~ ![](https://i.imgur.com/cfYQo6P.png =600x) id、位置、長寬、字體大小一樣可以從 attribute 裡面直接更改喔~ :::warning 注意:heavy_exclamation_mark: 每一個元件的 attribute 欄位裡面都可以填寫 id 名稱, 為了之後寫程式方便請盡量將他們改成直觀一點的名字!! ::: ### 使用 findViewById 1. 在 layout 中新增 button `android:id="@+id/btn`。id 的格式為 `@+id/你想取的名字`。 `android:text="calculate"`為按鈕上面的字樣。 ```kotli= <Button android:id="@+id/btn" android:layout_width="130dp" android:layout_height="54dp" android:layout_marginStart="152dp" android:layout_marginLeft="152dp" android:layout_marginTop="356dp" android:text="calculate" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> ``` 模擬器呈現: ![](https://i.imgur.com/OarilP0.png =350x) 2. 在 MainActivity.kt 中對按鈕進行綁定及操作。 在`setContentView(R.layout.activity_main)`下方加入: ```kotlin= val cal = findViewById<Button>(R.id.btn) ``` ### 新增點擊事件 BMI 計算器在壓下按鈕的那一刻需要達成: 1. 抓取使用者輸入的身高體重 2. 計算出bmi 3. 顯示 (Toast) 計算結果 在 MainActivity.kt 中對按鈕設定OnClickListener,並使用 Toast 顯示訊息, 格式為: `button的id名稱.setOnClickListener{ }` #### 參考範例 ```kotlin= package com.example.bmicalculator import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.Toast class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val cal = findViewById<Button>(R.id.btn) cal.setOnClickListener{ val w = findViewById<EditText>(R.id.input_weight).text.toString().toFloat() var h = findViewById<EditText>(R.id.input_height).text.toString().toFloat() h /= 100 val bmi = w / (h * h) Toast.makeText(this, bmi.toString(), Toast.LENGTH_LONG).show() } } } ``` ###### 抓取`textview` 裡面輸入的數值並將其轉為浮點數`.toFloat()` ###### 變數型態: * `val`:表示不可以更動的值 * `var`:可以更動的數值 ```kotlin= val w = findViewById<EditText>(R.id.input_weight).text.toString().toFloat() var h = findViewById<EditText>(R.id.input_height).text.toString().toFloat() ``` ###### 將計算結果呈現在UI上 * `Toast.LENGTH_LONG` 跳出結果後呈現較長時間 * `Toast.LENGTH_SHORT` 跳出結果後呈現較短時間 ```kotlin= Toast.makeText(this, bmi.toString(), Toast.LENGTH_LONG).show() ``` ### 成果展示(模擬器) ![](https://i.imgur.com/IkK9pzW.png =350x) --- ## 將 APP 在手機上驅動 1. 將手機用傳輸線連線到電腦 ~~廢話~~ 2. 打開 設定->關於手機->按下版本號碼(他要你點幾次就點幾次) 3. 確認更改為開發者模式之後再一次進入設定->系統->開發人員選項->開啟USB偵錯 4. 選擇自己的手機後 再一次執行程式 5. 可以結束ㄌ