Jetpack Composeを使ってみる

今回は「Jetpack Composeの設定」と「簡単なテキストを表示する」ところまでやってみたいと思います。

# Jetpack Composeの設定
developersの以下の記事を参考に設定を行いました。

[Android Studio で Jetpack Compose を使用する](https://developer.android.com/jetpack/compose/setup?authuser=1)

### 1. Composeに対応しているAndroid Studioをインストールする
以下のURLから「DOWNLOAD ARCTIC FOX CANARY 9」をインストールします。

[Preview release](https://developer.android.com/studio/preview?authuser=1)

### 2. Android Studioで新規Projectを作成する
プロジェクトを作成するときに、`APIレベル21以上（Android 5.0/Lollipop）`を選択します。

### 3. Kotlinのバージョンを`1.4.21`に変更する
```build.gradle
dependencies {
  classpath "com.android.tools.build:gradle:7.0.0-alpha09"
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.21"
}
```

## 4. Composeライブラリを依存関係に追加する
```app/build.gradle
// バージョンを上げれるよ、とAndroid Studioが教えてくれますが、そのままでOKです。
dependencies {

    implementation 'androidx.compose.ui:ui:1.0.0-alpha10'
    // Tooling support (Previews, etc.)
    implementation 'androidx.compose.ui:ui-tooling:1.0.0-alpha10'
    // Foundation (Border, Background, Box, Image, Scroll, shapes, animations, etc.)
    implementation 'androidx.compose.foundation:foundation:1.0.0-alpha10'
    // Material Design
    implementation 'androidx.compose.material:material:1.0.0-alpha10'
    // Material design icons
    implementation 'androidx.compose.material:material-icons-core:1.0.0-alpha10'
    implementation 'androidx.compose.material:material-icons-extended:1.0.0-alpha10'
    // Integration with observables
    implementation 'androidx.compose.runtime:runtime-livedata:1.0.0-alpha10'
    implementation 'androidx.compose.runtime:runtime-rxjava2:1.0.0-alpha10'
    // UI Tests
    androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.0.0-alpha10'
}
```

# 簡単なテキストを表示する

### setContentでText関数を呼び出す
レイアウトをXMLファイルで定義するのではなく、`setContent`ブロックでActivityのレイアウトを定義します。

そして、`setContent`ブロックの中で、コンポーズ可能な関数を呼び出します。

`setContentView(R.layout.activity_main)`は削除してOKです。

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Text("Hello World")
        }
    }
}
```

すると、以下の画面が表示されます。

![Screenshot_1615268824.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/458f1457-33e4-9285-b3d8-696781a50c73.png)


### コンポーズ可能な関数を作成する
コンポーズ可能な関数は、他のコンポーズ可能な関数から呼び出すことが出来ます。
つまり、`@Composable`アノテーションが設定された関数のスコープ内からのみ呼び出しが可能です。

```kotlin
// Good
@Composable
fun method01(name: String) = Text(text = name)
// Bad（@Composableがない関数で、Text関数を呼び出している）
fun method02(name: String) = Text(text = name)
```

MainActivity.ktを以下のように変更します。

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Greeting("World")
        }
    }
}

@Composable
fun Greeting(name: String) = Text(text = "Hello $name")
```

上記を実行すると、先ほどと同じ画面が表示されると思います。

### Android Studioで関数をプレビューする

Android Studioで関数をプレビューするには、作成した関数の`@Composable`アノテーションの前に、`@Preview`を設定します。

注意点として、プレビューする関数はパラメータを使用することが出来ません。

なので、`Greeting`関数は引数に`name: String`があるので、他の関数を定義する必要があります。

引数がある関数に`@Preview`を設定すると「`Composable function with non-default parameters are not supported in Preview unless they are annotated with @PreviewParameter`」エラーが表示されます。

```kotlin
// 引数があるので、@Previewアノテーションを付けることが出来ない
@Preview
@Composable
fun Greeting(name: String) = Text(text = "Hello $name")
```

`Greeting`関数を呼び出す別の関数「`PreviewGreeting`関数」を作成し、`@Preview`アノテーションを設定します。

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Greeting("World")
        }
    }
}

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

// 追加
@Preview
@Composable
fun PreviewGreeting() = Greeting(name = "Android")
```
`PreviewGreeting`関数を追加した後に再ビルドすると、Android Studioの右側にプレビューが表示されます。

![スクリーンショット 2021-03-09 15.38.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365643/2c94aa62-c3e9-5103-1811-611dc09d5ef1.png)