はじめに
Jetpack Composeは、ネイティブUIを構築するための新しい方法です。書き込み方法はFlutterと非常によく似ています。Flutterを知っている学生は、すぐに始めることができます。
公式ウェブサイト:https : //developer.android.com/jetpack/compose
公式デモ:https : //github.com/android/compose-samples
公式紹介:https : //developer.android.com/jetpack/compose/setup
環境とバージョン
最小サポートは、kotlin言語を使用する必要があるAndroid API 21バージョン5.0であり、最小バージョンはAndroid Studio 4.0です。
Jetpack Composeは現在実験段階にあり、現在は0.1-dev2であり、1.0の公式バージョンの1年前と推定されています。
以降のバージョンでは、kotlin機能が追加され、アニメーションやその他のパフォーマンスの問題が強化される場合があります。
既存のプロジェクトでの使用方法について:https :
//developer.android.com/jetpack/compose/setup#add-compose
使い方
サンプルコードがあり、AS 4.0で直接新しい空のプロジェクトを構成する:
関数の前に追加@Compose
の注釈は、あなたは、ウィジェットUIに似たフラッターに戻ることができ
、追加の@Compose
注釈機能お互いを呼び出すことができ、これらの機能は、プラグイン処理をコンパイルされます、したがって、関数がUIを生成しない場合は、この注釈を使用しないでください。
@Preview
アノテーションは右側でリアルタイムでプレビューできます。関数を変更した後、プレビューを更新します。アノテーションが追加された外部関数はパラメーターを持つことができませんが、パラメーターを持つ関数を内部にネストしてプレビューできます。次の@Preview
ような名前を後ろに追加できます。@Preview("Text preview")
列と行の概念はFlutterと同じです。主軸と第2軸の概念サイズmainAxisSize
と配置crossAxisAlignment
、およびコード例が含まれます。
@Composable
fun MyScreenContent(
names: List<String> = listOf("Android", "there"),
counterState: CounterState = CounterState()
) {
Column(crossAxisAlignment = CrossAxisAlignment.Center
crossAxisSize = LayoutSize.Expand,
mainAxisSize = LayoutSize.Expand) {
for (name in names) {
Greeting(name = name)
Divider(color = Color.Black)
}
Divider(color = Color.Transparent, height = 32.dp)
Counter(counterState)
}
}
@Preview("MyScreen preview")
@Composable
fun DefaultPreview() {
MyApp {
MyScreenContent()
}
}
HeightSpacer(24.dp)
またはWeightSpacer(24.dp)
を使用して、幅と高さの間隔を直接追加できます
公式の提案によると、UIを複数の小さなCompose関数に分割できます。各関数は最終的にプラグインによってコンパイルされてビューを生成し、これらのCompose関数を再利用できます。
@Composable
fun MyScreenContent(
names: List<String> = listOf("Android", "there"),
counterState: CounterState = CounterState()
) {
Column(modifier = ExpandedHeight, crossAxisAlignment = CrossAxisAlignment.Center) {
Column(modifier = Flexible(1f), crossAxisAlignment = CrossAxisAlignment.Center) {
for (name in names) {
Greeting(name = name)
Divider(color = Color.Black)
}
}
Counter(counterState)
}
}
Columnでは、パラメーター修飾子にExpandedHeightを設定できます。これは、高さmatch_parentを設定する意味と同様に、幅は同じです。
テーマの使用方法とテーマのカスタマイズ方法について
MaterialThemeには多くの色とフォントスタイルがあります。MaterialThemeを外側のレイヤーでラップした後、次のような内部のCompose関数でテーマデータを使用できます。style = +themeTextStyle { h1 }
@Composable
fun Greeting(name: String) {
Text (
text = "Hello $name!",
modifier = Spacing(24.dp),
style = +themeTextStyle { h1 }
color = +themeColor { surface }
)
}
次のようなコピー機能を使用して、既存のテーマの特定の属性値を変更できます。
textStyle = (+themeTextStyle { body1 }).copy(color = Color.Yellow)
カスタムテーマ
import androidx.compose.Composable
@Composable
fun CustomTheme(children: @Composable() () -> Unit) {
// TODO
}
import androidx.compose.Composable
import androidx.ui.core.CurrentTextStyleProvider
import androidx.ui.graphics.Color
import androidx.ui.material.MaterialColors
import androidx.ui.material.MaterialTheme
import androidx.ui.text.TextStyle
val green = Color(0xFF1EB980.toInt())
val grey = Color(0xFF26282F.toInt())
private val themeColors = MaterialColors(
primary = green,
surface = grey,
onSurface = Color.White
)
@Composable
fun CustomTheme(children: @Composable() () -> Unit) {
MaterialTheme(colors = themeColors) {
val textStyle = TextStyle(color = Color.Red)
CurrentTextStyleProvider(value = textStyle) {
children()
}
}
}
効果とメモ
メモの役割:
1.再構成する場合(つまり、UIコンポーネント内のモデルデータが変更されると、UIコンポーネントが再構築されます)、次のように状態値を保存します。
@Composable
fun MyScreenContent(
names: List<String> = listOf("Android", "there"),
counterState: CounterState = CounterState()
) { ... }
上記のコードに問題があります。再構築すると、新しいcounterStateオブジェクトが生成されるたびに、元のcounterState値が失われます。
次のようにメモを使用して修正した後、問題を解決できます。
@Composable
fun MyScreenContent(
names: List<String> = listOf("Android", "there"),
counterState: CounterState = +memo { CounterState() }
) { ... }
2.再編成するときは、複数の計算を防ぐために、いくつかの内部計算結果を覚えておいてください
コンポジションの途中で計算を実行する必要があるが、関数を再結合するたびに計算を実行したくない場合は、計算を覚えておくことができます。Composable関数を再結合しても、計算は再実行されません。
@Composable
fun Greeting(name: String) {
val formattedName = +memo { name.substringBefore(" ").toUpperCase() }
Text (
text = "Hello $formattedName!",
modifier = Spacing(24.dp),
style = +themeTextStyle { h3 }
)
}
@Preview
@Composable
fun DefaultPreview() {
MaterialTheme {
Greeting("Android 10")
}
}
たとえば、ここでのフォーマットされた名前の計算プロセスは、メモを使用した後は繰り返されませんが、この方法で記述されたバグがあります。2番目の呼び出しで別のパラメーターが渡されると、メモは元の結果を再利用するため、バグの原因となるため、変更が必要なパラメーターの場合、メモは次のように使用できます。
@Composable
fun Greeting(name: String) {
val formattedName = +memo(name) { name.substringBefore(" ").toUpperCase() }
Text (
text = "Hello $formattedName!",
modifier = Spacing(24.dp),
style = +themeTextStyle { h3 }
)
}
注釈付きのモデル
モデルアノテーションがデータクラスをマークした後、Compose関数でデータの変更を直接監視し、次の
ような表示を自動的に更新でき
ます。
@Model
class CounterState(var count: Int = 0)
使用:
@Composable
fun Counter(state: CounterState) {
Button(
text = "I've been clicked ${state.count} times",
onClick = {
state.count++
}
)
}
ステータス昇格、データフローダウン、イベントフローアップ
@Model
class FormState(var optionChecked: Boolean)
@Composable
fun Form(formState: FormState) {
Checkbox(
checked = formState.optionChecked,
onCheckedChange = { newState -> formState.optionChecked = newState })
}
在上面代码中,Checkbox的选中状态,在Checkbox和Form中都不保存,而改为由外部传入,原因是此时外部可能需要使用当前的状态值,那么由外部来创建并传递该参数到Compose函数中,这使得外部调用者提升了状态
⚠️注:構成可能な関数では、状態の昇格と呼ばれる、使用または制御できる唯一のメソッドであるため、関数の呼び出しに役立つ可能性のある状態を開示する必要があります。
状態の昇格の概念はFlutterと同じです。Compose+ Modelアノテーションの方法はMVVMのアイデアであり、利便性を必要とするため、将来はプロバイダー、BLOC、Reduxなどの関連する状態管理ライブラリもFlutterに導入されるはずです。データ状態管理の3つのライブラリがこれを行います。
データフローについて:親のComposable関数は、その子データを制御できます。Sub Compose UIは、グローバル変数またはグローバルデータストレージから読み取るべきではありません。Composable関数は必要な情報のみを受け取る必要があるため、親のComposable関数が提供できるすべてのものを呼び出すのではなく、可能な限りシンプルにする必要があります。
@Composable
fun MultipleGreetings(user: User = +memo { User("name", "surname") }) {
Column {
Greeting("${user.firstName} ${user.lastName}")
Greeting("Android 10")
Button(text = "Change name", onClick = {
user.firstName = "Changed"
user.lastName = "New surname"
})
}
}
@Composable
fun Greeting(name: String) {
val formattedName = +memo(name) { name.substringBefore(" ").toUpperCase() }
Text (
text = "Hello $formattedName!",
modifier = Spacing(24.dp),
style = +themeTextStyle { h3 }
)
}
比如上面代码中,Greeting从调用方Compose函数(MultipleGreetings)获取数据,作为参数传入,且Greeting只接收一个String,并不是整个User对象。
イベント通過
イベントはラムダコールバックを介して上がり続けます。子のComposable関数がイベントを受け取ると、変更は、情報を処理するComposableに反映されます。
この例では、onClickリスナーをパラメーターとして取るClickable関数(ライブラリーで使用可能)でGreetingのコンテンツをラップすることにより、Greetingをクリック可能にします。ただし、グリーティングは再利用可能な機能であり、ユーザーの操作を処理する方法がわかりません。次の例に示すように、ラムダを使用して、この情報を階層の最下部(Greetingでクリック可能なコンポーザブル)から最上位のコンポーザブル関数に伝達する必要があります。
@Composable
fun MultipleGreetings(user: User = +memo { User("name", "surname") }) {
val onClick = {
user.firstName = "Changed"
}
Column {
Greeting("${user.firstName} ${user.lastName}", onClick)
Greeting("Android 10", onClick)
Button(text = "Change name", onClick = onClick)
}
}
@Composable
fun Greeting(name: String, onClick: () -> Unit) {
val formattedName = +memo(name) { name.substringBefore(" ").toUpperCase() }
Clickable(onClick = onClick) {
Text (
text = "Hello $formattedName!",
modifier = Spacing(24.dp),
style = +themeTextStyle { h3 }
)
}
}
あいさつは、MultipleGreetingsに、親として渡されたラムダをパラメーターとして呼び出すことによってクリックされたことを伝えます。アプリケーションを実行すると、あいさつ文をクリックすると変更が反映され、上部のあいさつインスタンスが再グループ化されることがわかります。
Composeアプリのデータフロー。データはパラメーターで流れ、イベントはラムダで流れます。
作成と既存のビューの相互運用性
:作曲書き込み機能は、XMLで使用することができ、アンドロイドのような、書き込みに既存のビューのCompose方法でも使用することができます
要約:2019のように、作曲は、フラッターとスウィフトUIのプレゼンテーションに描くコードはシンプルで、リアルタイムプレビュー11月19日の現在のバージョンはわずか0.1でした。1.0の公式リリース後に、さらに多くの機能が更新されることが予想されます。毎日の小さなデモは、最初にComposeに慣れることができます。
リファレンス:https :
//codelabs.developers.google.com/codelabs/jetpack-compose-basics/#0
すばらしい!Flutterとまったく同じように記述されたAndroid Jetpack Compose UIコンポーネントライブラリの最新開発