Jetpack Composeをすこし触ってみた

この記事は[フラー Advent Calendar 2019 - Adventar](https://adventar.org/calendars/4155)の16日目の記事です

前日の15日目は[ShinYoshiaki](https://qiita.com/ShinYoshiaki)で、[Reduxをenjoyableにする](https://qiita.com/ShinYoshiaki/items/c1d871e175a89d41442f)でした。

---

はじめてAdvent Calendarを書きます（あと初めてQiitaに投稿します）

お題自由なので[Jetpack Compose](https://developer.android.com/jetpack/compose)を３時間くらい入門してみました。

ちなみにJetpack Composeはプレアルファです。

今回はテキストと画像の表示、遷移周りを作ってみました。

コードは最後にリンクを置いておきます。

時間が取れなかったので、間違っている部分等はあるとおもいますがご了承ください。

修正や追記する時間があればします。

## セットアップ

今回はAndroid Studio 4.0 CANARY 6を使用
> [Android Studio プレビュー  |  Android Developers](https://developer.android.com/studio/preview)


今回は新しくプロジェクトを作ります

1. 新規プロジェクトを作成

2. Select a Project Template で `Empty Compose Activity` を選択

3. min SDK は２１以上で

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

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            // ここにUI部分を書く
        }
    }
}
```
`setContent`に全てのUI部分が入ります。


### テキストを出してみる

テキストの表示です

resource引っ張るの割と楽だなぁと思いました。

```kotlin
@Composable
private fun TextTitle() {
    val title = +stringResource(R.string.text_title)
    val typography = +MaterialTheme.typography()
    Text(title, style = typography.h6)
}
```

### 画像読み込んでみる

イメージとベクターで使用する関数が違うようなのでどちらも紹介しておきます。

- Image

```kotlin
@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

```kotlin
@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は

```kotlin
modifier = Height(30.dp) wraps Expanded // 縦30dpの横match_parent的な感じ
modifier = Expanded                     // 縦横共にmatch_parent的な感じ
modifier = WidthExpanded                // 縦wrap_content 横match_parent的な感じ
```

のような指定ができます。
（詳しく検証していないので、的な感じというコメントで許してください）

## 画面遷移

他にもやりかたがあるのかわからないのですが、JetNewsを参考にして書きました。


```kotlin
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`をつけたものは値が更新されると再描画されるようです。


```kotlin
@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)
        }
    }
}

```
遷移先が書いてある


```kotlin
@Composable
fun HomeItem(data: StoryModel) {
    Column(modifier = ExpandedWidth) {
        Clickable(onClick = {
            navigateTo(Screen.Story(data.id))
        }) {
            ItemText(text = data.id)
        }
    }
}
```
実際遷移を実行する

## まとめ

時間足りなさすぎました。反省してます。

もう少し勉強してみようかは不明(Jetpack ComposeやるよりFlutterやってるほうがいいのでは？という意見も見える)

個人的には割とやってて楽しかったのと、コード量自体が減る・・・気はしないですね。

また、いままで普通にできたことを再度調べてやるのだけれども、調べてもでてこないことが多かったり・・
（プレアルファだから仕方ないね）

またどこかのタイミングで再挑戦してみようとは思います。

ちなみに今回のコードは[こちら](https://github.com/a1ia3kids/JetpackCompose-Sample)

## 参考
[compose-samples/JetNews at master · android/compose-samples · GitHub](https://github.com/android/compose-samples/tree/master/JetNews)

[Exploring Jetpack Compose: Container – Joe Birch](https://joebirch.co/2019/11/26/exploring-jetpack-compose-container/)