Jetpack (七)Android Compose 基礎<3>

Jetpack Compose 是用于構建原生 Android 界面的新工具包。Jetpack Compose 使用更少的代碼、強大的工具和直觀的 Kotlin API 簡化并加快了 Android 上的界面開發。

在本教程中,您將使用聲明性的函數構建一個簡單的界面組件。您無需修改任何 XML 布局,也不需要直接創建界面微件,而只需要調用 Jetpack Compose 函數來聲明您想要的元素,Compose 編譯器即會完成后面的所有工作。

1.0 API Surface 功能完整,但可能包含錯誤

之前,簡單用兩篇文章認識了下 Compose 使用,接下來拆分知識點學習。

1. 可組合函數

Jetpack Compose 是圍繞可組合函數構建的。這些函數可讓您以編程方式定義應用界面,只需描述應用界面的形狀和數據依賴關系,而不必關注界面的構建過程。如需創建可組合函數,只需將 @Composable 注釋添加到函數名稱中即可。

添加文本元素 Text("Hello world!")

首先,按照 Jetpack Compose 設置說明操作,使用 Empty Compose Activity 模板創建一個應用。默認模板已包含一些 Compose 元素,但我們下面要逐步進行構建。首先,刪除“Greeting”和“Default Preview”函數,然后從 MainActivity 中刪除 setContent 塊,將該 Activity 留空。編譯并運行您的空白應用。

現在,向空白的 Activity 中添加文本元素??梢酝ㄟ^定義內容塊并調用 Text() 函數來實現此目的。

setContent 塊定義了 Activity 的布局。我們不使用 XML 文件來定義布局內容,而是調用可組合函數。Jetpack Compose 使用自定義 Kotlin 編譯器插件將這些可組合函數轉換為應用的界面元素。例如,Compose 界面庫定義了 Text() 函數;您可以調用該函數在應用中聲明文本元素。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}
  

定義可組合函數

可組合函數只能在其他可組合函數的范圍內調用。要使函數成為可組合函數,請添加 @Composable 注釋。如需嘗試此操作,請定義一個 Greeting() 函數并向其傳遞一個名稱,然后該函數就會使用該名稱配置文本元素。

在 Android Studio 中預覽函數

當前的 Canary 版 Android Studio 允許您在 IDE 中預覽可組合函數,而無需將應用下載到 Android 設備或模擬器中。主要限制在于,可組合函數不能接受任何參數。因此,您無法直接預覽 Greeting() 函數,而是需要創建另一個名為 PreviewGreeting() 的函數,由該函數使用適當的參數調用 Greeting()。請在 @Composable 上方添加 @Preview 注釋。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Greeting("Android")
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text (text = "Hello $name!")
}
  

@Preview
@Composable
fun PreviewGreeting() {
    Greeting("Android")
}
  

重新構建您的項目。由于新的 previewGreeting() 函數未在任何位置受到調用,因此應用本身不會更改,但 Android Studio 會添加一個預覽窗口。此窗口會顯示由標有 @Preview 注釋的可組合函數創建的界面元素的預覽。任何時候,如需更新預覽,請點擊預覽窗口頂部的刷新按鈕。

2. 布局

從一些文本開始, 會出現重疊現象

返回到您的 Activity,用新的 NewsStory() 函數替換 Greeting() 函數。在本教程的其余部分,您將修改該 NewsStory() 函數,并且不會再更改 Activity 代碼。

最佳做法是單獨創建不會被應用調用的預覽函數;專門的預覽函數可以提高性能,并且有利于以后更輕松地設置多個預覽。因此,請創建一個默認預覽函數,該函數的唯一用途就是調用 NewsStory() 函數。隨著您按照本教程對 NewsStory() 進行更改,預覽內容會反映您所做的更改。

這段代碼會在內容視圖中創建三個文本元素。但是,由于我們未提供有關如何排列這三個文本元素的信息,因此它們會相互重疊,使文本無法閱讀。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            NewsStory()
        }
    }
}

@Composable
fun NewsStory() {
    Text("A day in Shark Fin Cove")
    Text("Davenport, California")
    Text("December 2018")
}

@Preview
@Composable
fun DefaultPreview() {
    NewsStory()
}
  

使用 Column,解決布局問題

Column 函數可讓您垂直堆疊元素。向 NewsStory() 函數中添加一個 Column。

默認設置會直接將所有子項逐個堆疊起來,中間不留間距。Column 本身位于內容視圖的左上角。

@Composable
fun NewsStory() {
    Column {
        Text("A day in Shark Fin Cove")
        Text("Davenport, California")
        Text("December 2018")
    }
}
  

向 Column 中添加樣式設置

通過將參數傳遞給 Column 調用,可以配置 Column 的尺寸和位置,以及 Column 的子項的排列方式。

該設置具有以下含義:

modifier:可供您配置布局。本例中使用了一個 Modifier.padding 修飾符,將 Column 內嵌在周圍的視圖中。

@Composable
fun NewsStory() {
    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Text("A day in Shark Fin Cove")
        Text("Davenport, California")
        Text("December 2018")
    }
}
  

添加圖片

我們想在文本上面添加圖片。使用資源管理器將這張名為 header 的照片添加到應用的可繪制資源。

現在,修改您的 NewsStory() 函數。您將添加對 Image() 的調用,以將圖片放入 Column?!癴oundation”軟件包中提供了這些可組合項,您可能需要添加該軟件包。請參閱 Jetpack Compose 設置說明。圖片的比例會有問題,但沒關系,您可以在下一步中糾正此問題。

@Composable
fun NewsStory() {
    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Image(
            painter = painterResource(R.drawable.header),
            contentDescription = null
        )

        Text("A day in Shark Fin Cove")
        Text("Davenport, California")
        Text("December 2018")
    }
}
  

圖片已添加到布局中,但其尺寸尚未調整為適當大小。如需設置圖片樣式,請將尺寸 Modifier 傳遞給對 Image() 的調用。

height(180.dp):指定圖片的高度。
fillMaxWidth():指定圖片的寬度應足以填充所屬布局。
您還需要向 Image() 傳遞一個 contentScale 參數:

contentScale = ContentScale.Crop:指定圖片應填充 Column 的整個寬度,并根據需要剪裁為適當的高度。

@Composable
fun NewsStory() {
    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Image(
            painter = painterResource(R.drawable.header),
            contentDescription = null,
            modifier = Modifier
                .height(180.dp)
                .fillMaxWidth(),
            contentScale = ContentScale.Crop
        )

        Text("A day in Shark Fin Cove")
        Text("Davenport, California")
        Text("December 2018")
    }
}
  

添加 Spacer,將圖片與標題分開。

@Composable
fun NewsStory() {
    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Image(
            painter = painterResource(R.drawable.header),
            contentDescription = null,
            modifier = Modifier
                .height(180.dp)
                .fillMaxWidth(),
            contentScale = ContentScale.Crop
        )
        Spacer(Modifier.height(16.dp))

        Text("A day in Shark Fin Cove")
        Text("Davenport, California")
        Text("December 2018")
    }
}
  

3. Material Design

Compose 旨在支持 Material Design 原則。它的許多界面元素都原生支持 Material Design。使用 Material 微件來設置應用的樣式。

采用形狀

Material Design 系統的關鍵要素之一就是 Shape。使用 clip() 函數對圖片的四角進行圓角化處理。

Shape 不可見,但圖片已被剪裁以匹配 Shape,因此現在呈現輕微的圓角。

設置文本樣式

借助 Compose,您可以輕松遵循 Material Design 原則。將 MaterialTheme 應用到您創建的組件。

差別可能不太明顯,但文本現在采用了 MaterialTheme 的默認文本樣式。接下來,對每個文本元素應用特定的段落樣式。

但有時,一篇文章的標題很長,我們不希望過長的標題影響應用的外觀。嘗試更改第一個文本元素。

配置文本元素,將長度上限設置為 2 行。如果文本很短,不超過此限制,則此設置沒有影響;但如果文本過長,顯示的文本就會被自動截短。

@Composable
fun NewsStory() {
    MaterialTheme {
        val typography = MaterialTheme.typography
        Column(
            modifier = Modifier.padding(16.dp)
        ) {
            Image(
                painter = painterResource(R.drawable.header),
                contentDescription = null,
                modifier = Modifier
                    .height(180.dp)
                    .fillMaxWidth()
                    .clip(shape = RoundedCornerShape(4.dp)),
                contentScale = ContentScale.Crop
            )
            Spacer(Modifier.height(16.dp))

            Text(
                "A day wandering through the sandhills " +
                     "in Shark Fin Cove, and a few of the " +
                     "sights I saw",
                style = typography.h6,
                maxLines = 2,
                overflow = TextOverflow.Ellipsis)
            Text("Davenport, California",
                style = typography.body2)
            Text("December 2018",
                style = typography.body2)
        }
    }
}
  
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯系作者。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容