使用 Compose 創(chuàng)建一款交互式?Dice Roller?Android 應用。
完成:
- 定義可組合函數。
- 使用組合創(chuàng)建布局。
- 使用?
Button
?可組合項創(chuàng)建按鈕。 - 導入?
drawable
?資源。 - 使用?
Image
?可組合項顯示圖片。 - 使用可組合項構建交互式界面。
- 使用?
remember
?可組合項將組合中的對象存儲到內存中。 - 使用?
mutableStateOf()
?函數刷新界面以創(chuàng)建可觀察對象。
一 創(chuàng)建項目?
- 在 Android Studio 中,依次點擊?File > New > New Project。
- 在?New Project?對話框中,選擇?Empty Activity,然后點擊?Next
- 在?Name?字段中,輸入?
Dice Roller
。 - 在?Minimum SDK?字段中,從菜單中選擇最低 API 級別 24 (Nougat),然后點擊?Finish。
?二?創(chuàng)建布局基礎架構
主布局初始代碼如下:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Greeting("Android")
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
MyApplicationTheme {
Greeting("Android")
}
}
仿真運行,可以看到 Hello Andriod輸出。
1 重構示例代碼
您需要更改一些生成的代碼,使其更貼近 Dice Roller 應用的主題。
如您在最終應用的屏幕截圖中看到的那樣,應用中有骰子的圖片和用于擲骰子的按鈕。您將構建可組合函數以反映此架構。
如需重構示例代碼,請執(zhí)行以下操作:
- 移除?DefaultPreview()?函數。
- 創(chuàng)建一個帶有?@Composable?注解的?DiceWithButtonAndImage()?函數。
該可組合函數代表布局的界面組件,還包含按鈕點擊和圖片顯示邏輯。
- 移除?Greeting(name: String)?函數。
- 創(chuàng)建一個帶有?@Preview?和?@Composable?注解的?DiceRollerApp()?函數。
由于該應用僅包含一個按鈕和一張圖片,因此不妨將該可組合函數視為應用本身。因此,我們稱之為?DiceRollerApp()?函數。?
@Preview
@Composable
fun DiceRollerApp() {
}
@Composable
fun DiceWithButtonAndImage() {
}
由于移除了?Greeting()?函數,因此?DiceRollerTheme()?lambda 正文中對?Greeting("Android")?的調用會突出顯示為紅色。這是因為編譯器無法再找到對該函數的引用。
刪除?onCreate()?方法中的?setContent{}?lambda 內的所有代碼。
- 在?setContent{}?lambda 正文中,調用?DiceRollerTheme{}?lambda,然后在?DiceRollerTheme{}?lambda 內調用?DiceRollerApp()?函數。
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DiceRollerTheme {
DiceRollerApp()
}
}
}
}
- 在?
DiceRollerApp()
?函數中,調用?DiceWithButtonAndImage()
?函數。
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage()
}
?2?添加修飾符
Compose 使用 Modifier 對象,該對象是用于修飾或修改 Compose 界面元素行為的元素的集合。您將使用該對象來設置 Dice Roller 應用組件的界面組件樣式。
如需添加修飾符,請執(zhí)行以下操作:
- 將 DiceWithButtonAndImage() 函數修改為接受 Modifier 類型的 modifier 實參,并為其分配默認值 Modifier。
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
}
?
該函數允許傳入 modifier 形參。modifier 形參的默認值為 Modifier 對象,因此是方法簽名的 = Modifier 部分。借助某個形參的默認值,未來調用該方法的任何調用方都可以決定是否為該形參傳遞值。如果它們傳遞自己的 Modifier 對象,則可以自定義界面的行為和裝飾。如果它們選擇不傳遞 Modifier 對象,系統會假定使用默認值,即普通的 Modifier 對象。您可以將這種做法應用于任何形參。如需詳細了解默認實參,請參閱默認實參。
- 現在,DiceWithButtonAndImage() 可組合項具有修飾符參數,請在調用該可組合項時傳遞修飾符。由于 DiceWithButtonAndImage() 函數的方法簽名已更改,因此在調用該方法時,應傳入包含所需裝飾的 Modifier 對象。Modifier 類負責對 DiceRollerApp() 函數中的可組合對象進行裝飾或向其添加行為。在本例中,需要向傳遞到 DiceWithButtonAndImage() 函數的 Modifier 對象添加一些重要的裝飾。
- 將?fillMaxSize()?方法鏈接到?
Modifier
?對象,以便讓布局填充整個屏幕。 - 將?
wrapContentSize()
?方法鏈接到?Modifier
?對象,然后傳遞?Alignment.Center
?作為實參以將組件居中。Alignment.Center
?會指定組件同時在水平和垂直方向上居中。
這樣,fun DiceRollerApp()函數的最終代碼如下:
@Preview
@Composable
fun DiceRollerApp() {
DiceWithButtonAndImage(modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.Center))
}
?注意:
- import androidx.compose.ui.Modifier 語句會導入 androidx.compose.ui.Modifier 軟件包,以便您引用 Modifier 對象。
- fllMaxSize() 和 wrapContentSize() 的 import 語句分別是 import androidx.compose.foundation.layout.fillMaxSize 和 import androidx.compose.foundation.layout.wrapContentSize。
- Alignment 對象的 import 語句為 import androidx.compose.ui.Alignment。
三 創(chuàng)建垂直布局?
在 Compose 中,垂直布局是使用?Column()
?函數創(chuàng)建的。
Column()?函數是一種可組合項布局,它會按垂直序列放置其子級。在預期的應用設計中,骰子圖片應該垂直顯示在擲骰子按鈕的上方。
如需創(chuàng)建垂直布局,請執(zhí)行以下操作:
- 在?DiceWithButtonAndImage()?函數中,添加一個?Column()?函數。
- 將?modifier?實參從?DiceWithImageAndButton()?方法簽名傳遞給?Column()?的修飾符實參。modifier?實參可確保?Column()?函數中的可組合項遵守對?modifier?實例調用的約束條件。
- 將?horizontalAlignment?實參傳遞給?Column()?函數,然后將其值設為?Alignment.CenterHorizontally。這可以確保列中的子項相對于寬度在設備屏幕上居中。
?
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
Column (
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {}
}
四 添加按鈕
- 在 strings.xml 文件中,添加一個字符串并將其設為 Roll 值。
- 在 Column() 的 lambda 正文中,添加 Button() 函數。
- 在 MainActivity.kt 文件中,將 Text() 函數添加到函數 lambda 正文中的 Button()。
- 將 roll 字符串的字符串資源 ID 傳遞到 stringResource() 函數,并將結果傳遞到 Text 可組合項。?
strings.xml 文件:?
<string name="roll">Roll</string>
?
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = { /*TODO*/ }) {
Text(stringResource(R.string.roll))
}
}
}
五 添加圖片
應用的另一個重要組件是骰子圖片,在用戶點按?Roll?按鈕后,該圖片會顯示結果。
1 導入圖片
預先準備好?6 個骰子圖片文件,都是200*250dp,其骰子點數分別為 1 到 6。
將其放到項目目錄\app\src\main\res\drawable下。
2 添加 Image 可組合項?
骰子圖片應顯示在 Roll 按鈕上方。Compose 本身會依序放置界面組件。也就是說,哪個可組合項聲明在先,就會先行顯示。這意味著,首先聲明的可組合項會顯示在之后聲明的可組合項的上面或前面。Column 可組合項中的可組合項會在設備上按上下順序顯示。在該應用中,您將使用 Column 來垂直堆疊可組合項,因此首先在 Column() 函數中聲明的可組合項會先于同一 Column() 函數中之后才聲明的可組合項顯示。
如需添加 Image 可組合項,請執(zhí)行以下操作:
- 在 Column() 函數正文中,在 Button() 函數前面創(chuàng)建一個 Image() 函數。
- 向 Image() 函數傳遞一個 painter 實參,然后為其分配接受可繪制資源 ID 實參的 painterResource 值。目前,請傳遞以下資源 ID:R.drawable.dice_1 實參。
- 每當您在應用中創(chuàng)建圖片時,都應該提供所謂的“內容說明”。內容說明是 Android 開發(fā)的重要組成部分。內容說明能夠向各界面組件添加說明,以提高無障礙性。如需詳細了解內容說明,請參閱描述每個界面元素。您可以將內容說明作為形參傳遞到圖片。?
這樣,fun DiceWithButtonAndImage()函數體就變?yōu)?/p>
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(
painter = painterResource(R.drawable.dice_1),
contentDescription = "1"
)
Button(onClick = { /*TODO*/ }) {
Text(stringResource(R.string.roll))
}
}
預覽畫面為:?
?
注意:
- Image 可組合項的 import 語句為 import androidx.compose.foundation.Image。
?六?構建擲骰子邏輯
現在所有必要的可組合項均已存在,接下來您可以修改應用,以便用戶能點按按鈕來擲出骰子?
1?將 Button 設為可交互
- 在 DiceWithButtonAndImage() 函數中的 Column() 函數前面,創(chuàng)建一個 result 變量并將其值設為等于 1。
- 查看 Button 可組合項。您會發(fā)現,系統正在向它傳遞一個 onClick 形參,該形參已設為內含 /*TODO*/ 注釋的一對大括號。在本例中,大括號代表所謂的“l(fā)ambda”,大括號內的區(qū)域是 lambda 正文。將函數作為實參進行傳遞時,相應過程也可稱為回調。
- 在 Button() 函數中,從 onClick 形參的 lambda 正文的值中移除 /*TODO*/ 注解。
- 擲骰子是隨機的。為了在代碼中反映這一點,您需要使用正確的語法來生成隨機數字。在 Kotlin 中,您可以對一個數字范圍使用 random() 方法。在 onClick lambda 正文中,將 result 變量的范圍設為 1 到 6,然后針對該范圍調用 random() 方法。請注意,在 Kotlin 中,范圍由范圍中的第一個數字與范圍中的最后一個數字之間的兩個句點指定。??
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
var result = 1
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(painter = painterResource(imageResource), contentDescription = result.toString())
Button(onClick = { result = (1..6).random() }) {
Text(stringResource(R.string.roll))
}
}
}
現在,該按鈕可點按了,但點按該按鈕并不會產生任何可見的變化,因為您仍需構建該功能。
?2?為 Dice Roller 應用添加條件
- 將 result 變量設為 remember 可組合項。remember 可組合項需要傳遞函數。
- 在 remember 可組合項正文中,傳入 mutableStateOf() 函數,然后向該函數傳遞 1 實參。mutableStateOf() 函數會返回一個可觀察對象。稍后,您會詳細了解可觀察對象,但目前這基本上意味著,當 result 變量的值變化時,系統會觸發(fā)重組、反映結果值并刷新界面。
- 在 result 變量實例化的下方,創(chuàng)建一個不可變的 imageResource 變量,并將其設為接受 result 變量的 when 表達式,然后將每個可能的結果設為其可繪制對象。?
- 將傳遞到?
Image
?可組合項的?painterResource
?形參的 ID 從?R.drawable.dice_1
?可繪制對象更改為?imageResource
?變量。 - 通過將?
result
?變量轉換為包含?toString()
?的字符串并將其作為?contentDescription
?傳遞,更改?Image
?可組合項的?contentDescription
?形參以反映?result
?變量的值。
這樣,fun DiceWithButtonAndImage()函數的最終代碼如下:
@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
var result by remember {
mutableStateOf(1)
}
Column (
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
val imageResource = when (result) {
1 -> R.drawable.dice_1
2 -> R.drawable.dice_2
3 -> R.drawable.dice_3
4 -> R.drawable.dice_4
5 -> R.drawable.dice_5
else -> R.drawable.dice_6
}
Image(
painter = painterResource(id = imageResource),
contentDescription = result.toString()
)
Button(onClick = { result = (1..6).random() }) {
Text(stringResource(R.string.roll))
}
}
}
?
七 運行應用。
現在,Dice Roller?應用應該完全可以正常運行了!文章來源:http://www.zghlxwxcb.cn/news/detail-829560.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-829560.html
到了這里,關于安卓學習筆記之五:Android Studio_骰子案例3(Kotlin搭配 Jetpack Compose實現)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!