Jetpack Compose學習(1)——從登入頁開始入門

one發表於2021-08-11

原文地址:Jetpack Compose學習(1)——從登入頁開始入門 | Stars-One的雜貨小窩

Jetpack Compose UI在前幾天出了1.0正式版,之前一直還在觀望,終於是出了正式版 ? 趁著無事,來篇入門教程,希望給各位一點參考

注:由於compose UI使用了kotlin的DSL語言特性,所以需要熟悉Kotlin

Jetpack Compose介紹

Jetpack Compose 是一個用於構建原生 Android UI 的現代工具包。Jetpack Compose 用更少的程式碼、強大的工具和直觀的 Kotlin API 簡化並加速了 Android 上的 UI 開發。

Jetpack Compose使用了宣告式來編寫UI,本質上就是用程式碼寫佈局,這裡說的程式碼不是特指,主要是與htmlxml等標識語言進行區別,在xml等語言中,我們無法使用if或迴圈等結構體來構造UI,而JetCompose Compose 而可以實現這點,這樣會讓我們佈局更加靈活

如果之前各位也是接觸過Flutter,就會和我有一樣的體會,Jetpack Compose裡面的元件類定義跟Flutter那邊十分一致,我猜測肯定是有借鑑,畢竟那邊也是Google公司旗下的團隊整的

過多的就不說了,上正文吧 ?

簡單Hello World

首先,你需要一臺聯網的電腦,下載Android Studio最新版(2020.3.1) ?,好久沒升級了,介面都感覺煥然一新了 ?

之後的環境配置這裡不多說了,下SDK,下模擬器,新人來 估計得折騰一天 由於我之前就已經下載過Android Studio,這裡直接下載好之後就可以使用了

我們按照官方的教程,直接新建一個Jetpack Compose專案

之後常規操作 ,填寫相關的包名即可新建了,之後又是等待下載相關依賴的東西,一切下載完畢就準備OK了

可一看右邊,一個紅色的背景,頓時人就有點煩了,還好不是什麼大問題,它提示我們需要build一下專案

行吧,我build一下,然後,人傻了,直接爆紅了?

一看提示 好傢伙,最低的Java環境要11了,我也是服了,百度一搜

原來是Android官方那邊的坑,直接把gradle升級到最新版,你說你升級就升級吧,可沒想到gradle那邊最新版棄用JDK8了

解決方法有兩個

  • 更改Android Gradle Plugin和Gradle版本
  • 使用JDK11環境

更改Android Gradle Plugin和Gradle版本,也就是下圖這兩個東西,自己參考下之前舊版本專案的版本號改即可

PS: 通過File -> Project Structure開啟下面的介面

下圖是我自己舊專案使用的版本號,各位可以參考下

舊專案使用的版本號

至於換JDK11,其實也是比較簡單,我是環境變數都是用著JDK8,因為還有舊專案需要使用(TornadoFx),所以,我們只改專案裡使用的JDK版本即可

進到設定裡修改即可,如下圖

Android Studio其實內建有個JDK11,我們直接使用這個即可,而且,不會影響其他新開的專案

gradle使用JDK11

經過上面的設定後,我們可以重新build下專案,可以發現右側已經可以預覽了

我們先簡單分析一下程式碼

onCreate()中,有個setContent(),用來設定頁面的主體內容,我們先不管ComposeDemoThemeSurface,Greeting("Android")是我們要關心的

setContent {
    ComposeDemoTheme {
        // A surface container using the 'background' color from the theme
        Surface(color = MaterialTheme.colors.background) {
            Greeting("Android")
        }
    }
}

此方法上有個註解@Composable,用來表示當前方法返回的是一個元件,我們可以更改其中的數值,可以看到右側會實時的進行變化

提示: 實時渲染只針對數值的改變,如果你新增一個元件,是沒有實時變化效果的,需要重新build一次

下面也有個方法,除了@Composable註解,還有有個@Preview,Preview主要是標明用來預覽的

標有@Preview註解的方法,不能存在有引數,否則無法預覽

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemoTheme {
        // A surface container using the 'background' color from the theme
        Surface(color = MaterialTheme.colors.background) {
            Greeting("Android")
        }
    }
}

登入頁實現

上面也是比較簡單的講解了下程式碼,下面我們來個登入頁例項來操作下吧

與Flutter一樣,Jetpack Compose沒有線性佈局(LinearLayout),但有Row和Column兩個佈局,從名字可以看得出來,一種是水平佈局,一種是垂直佈局

我們先簡單搭建個登入頁面

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    ComposeDemoTheme {
        Column() {
            Row() {
                Text(text = "使用者名稱")
                TextField(value = "", onValueChange = {str -> Log.e("test",str)})
            }
            Row() {
                Text(text = "密碼")
                TextField(value = "", onValueChange = {str -> Log.e("test",str)})
            }
            TextButton(onClick = { }) {
                Text(text = "登入")
            }
        }
    }
}

上面程式碼中出現了幾個元件Text,TextField和TextButton,字面意思很好理解

元件名 作用
Text 文字
TextField 輸入框
TextButton 文字按鈕

預覽效果如下圖所示:

測試的發現,無法輸入文字,這是怎麼回事呢?

因為Jetpack Compose使用了類似MVVM的資料繫結的方式,所以,我們得給輸入框繫結一個變數,onValueChange方法數值改變的時候會回撥,我們在回撥更改變數的數值即可達到更改UI的效果

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    var name by remember { mutableStateOf("") }
    var pwd by remember { mutableStateOf("") }

    ComposeDemoTheme {
        Column() {
            Row() {
                Text(text = "使用者名稱")
                TextField(value = name, onValueChange = { str -> name = str })
            }
            Row() {
                Text(text = "密碼")
                TextField(value = pwd, onValueChange = { str -> pwd = str })
            }
            TextButton(onClick = { }) {
                Text(text = "登入")
            }
        }
    }
}

上面程式碼出現了remembermutableStateOf的兩個關鍵字,但本章作為入門篇,先暫時不講解過多知識,先放著,後續再進行補充

最後,我們還差一步,就是判斷輸入的賬號和密碼是否正確,然後彈出登入失敗或登入成功的提示

這裡,我準備使用傳統簡單的Toast進行提示,但是Toast需要傳一個Context,由於元件的那個函式是寫在Activity外面的,所以是拿不到Activity本身的,但是我們可以把Activity本身傳到方法裡(但不確定我這方法規不規範)

PS:看了下對話方塊的使用,覺得有些複雜,也是放在之後再講解吧

@Composable
fun DefaultPreview(context: Activity) {
    var name by remember { mutableStateOf("") }
    var pwd by remember { mutableStateOf("") }

    ComposeDemoTheme {
        Column() {
            Row() {
                Text(text = "使用者名稱")
                TextField(value = name, onValueChange = { str -> name = str })
            }
            Row() {
                Text(text = "密碼")
                TextField(value = pwd, onValueChange = { str -> pwd = str })
            }
            TextButton(onClick = {
                if (name == "test" && pwd == "123") {
                    Toast.makeText(context, "登入成功", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(context, "登入失敗", Toast.LENGTH_SHORT).show()
                }
            }) {
                Text(text = "登入")
            }
        }
    }
}

最後效果如下圖所示

登入動圖

參考

相關文章