この記事はフラー Advent Calendar 2019 - Adventarの16日目の記事です
前日の15日目はShinYoshiakiで、Reduxをenjoyableにするでした。
はじめてAdvent Calendarを書きます(あと初めてQiitaに投稿します)
お題自由なのでJetpack Composeを3時間くらい入門してみました。
ちなみにJetpack Composeはプレアルファです。
今回はテキストと画像の表示、遷移周りを作ってみました。
コードは最後にリンクを置いておきます。
時間が取れなかったので、間違っている部分等はあるとおもいますがご了承ください。
修正や追記する時間があればします。
セットアップ
今回はAndroid Studio 4.0 CANARY 6を使用
今回は新しくプロジェクトを作ります
-
新規プロジェクトを作成
-
Select a Project Template で
Empty Compose Activity
を選択 -
min SDK は21以上で
languageはkotlinしか選べないです。
おまじない
build.gradle(.app)
android{
...
buildFeatures {
compose true
}
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version")
implementation("androidx.compose:compose-runtime:$compose_version")
implementation("androidx.ui:ui-framework:$compose_version")
implementation("androidx.ui:ui-layout:$compose_version")
implementation("androidx.ui:ui-material:$compose_version")
implementation("androidx.ui:ui-foundation:$compose_version")
implementation("androidx.ui:ui-animation:$compose_version")
implementation "androidx.ui:ui-tooling:$compose_version"
implementation('androidx.appcompat:appcompat:1.1.0')
implementation('androidx.activity:activity-ktx:1.0.0')
implementation "androidx.core:core-ktx:1.1.0"
}
基本的なUI
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// ここにUI部分を書く
}
}
}
setContent
に全てのUI部分が入ります。
テキストを出してみる
テキストの表示です
resource引っ張るの割と楽だなぁと思いました。
@Composable
private fun TextTitle() {
val title = +stringResource(R.string.text_title)
val typography = +MaterialTheme.typography()
Text(title, style = typography.h6)
}
画像読み込んでみる
イメージとベクターで使用する関数が違うようなのでどちらも紹介しておきます。
- Image
@Composable
private fun Image() {
val image = +imageResource(R.drawable.image)
Container(
modifier = Size(150.dp, 180.dp)
) {
Clip(shape = RoundedCornerShape(8.dp)) {
DrawImage(image = image)
}
}
}
- Vector
@Composable
private fun Vector() {
val vector = +vectorResource(R.drawable.ic_baseline_arrow_back_24)
Container(
modifier = Size(30.dp, 30.dp)
){
DrawVector(
vectorImage = vector,
tintColor = Color.Black,
)
}
}
Containerは箱、modifierでサイズの指定しています。
modifierは
modifier = Height(30.dp) wraps Expanded // 縦30dpの横match_parent的な感じ
modifier = Expanded // 縦横共にmatch_parent的な感じ
modifier = WidthExpanded // 縦wrap_content 横match_parent的な感じ
のような指定ができます。
(詳しく検証していないので、的な感じというコメントで許してください)
画面遷移
他にもやりかたがあるのかわからないのですが、JetNewsを参考にして書きました。
sealed class Screen {
object Home : Screen()
data class Story(val id: String) : Screen()
}
@Model
object AppStatus {
var currentScreen: Screen = Screen.Home
}
fun navigateTo(destination: Screen) {
AppStatus.currentScreen = destination
}
@Model
をつけたものは値が更新されると再描画されるようです。
@Composable
fun SampleApp() {
MaterialTheme {
Content()
}
}
@Composable
private fun Content() {
Crossfade(current = AppStatus.currentScreen) { screen ->
when (screen) {
is Screen.Home -> HomeScreen()
is Screen.Story -> TextScreen(id = screen.id)
}
}
}
遷移先が書いてある
@Composable
fun HomeItem(data: StoryModel) {
Column(modifier = ExpandedWidth) {
Clickable(onClick = {
navigateTo(Screen.Story(data.id))
}) {
ItemText(text = data.id)
}
}
}
実際遷移を実行する
まとめ
時間足りなさすぎました。反省してます。
もう少し勉強してみようかは不明(Jetpack ComposeやるよりFlutterやってるほうがいいのでは?という意見も見える)
個人的には割とやってて楽しかったのと、コード量自体が減る・・・気はしないですね。
また、いままで普通にできたことを再度調べてやるのだけれども、調べてもでてこないことが多かったり・・
(プレアルファだから仕方ないね)
またどこかのタイミングで再挑戦してみようとは思います。
ちなみに今回のコードはこちら
参考
compose-samples/JetNews at master · android/compose-samples · GitHub