Intellij IdeaからJetpack Composeを使ってみる


初投稿です。

# Jetpack Compose

[Jetpack Compose](https://developer.android.com/jetpack/compose) が2021年7月に正式リリースになりました。公式サイトによると
- XMLを使う煩雑さの軽減
- 宣言型UI(UIの構築だけでいい感じによしなにしてくれる)
- KotlinだからAPIを直接呼べる

とかを売りにする

>ネイティブ UI をビルドするための Android の最新ツールキット

なんだそうです。
しかも聞くところによるとマルチスレッドにいい感じに対応して、
UIの更新が必要なら非常に ~~変態的な~~ 高度な実装により更新を必要とする部分だけ再描画するそうで。
未来を感じる技術です。ｲﾔｰﾀﾉｼｿｳﾀﾞﾅｰ

...

..

>2021年7月に正式リリース

＿人人人人人人人＿
＞　2021年7月　＜
￣Y^Y^Y^Y^Y^Y￣

### 出遅れました

約一年遅れです。忙しかったんです。

それでやっとこの度試しに使ってみることしたのですが、~~GoogleのAndroid Studio押しがすごくて~~ググっても純Intellij Ideaで使ってる人があんまり出てこない(Compose for Desktopばっかり出てくる)
ので、いっちょ使えるか試してやろうと思った次第でございます。

## 環境
- Windows 10
- Intellij Idea
    - 2022.1 (Community Edition)
    - ビルド #IC-221.5080.210
    - Japanese Language Pack インストール済み

## 環境構築

### Plugin
バンドルの Androidプラグインは有効化しておきます

#### [Jetpack Compose プラグイン](https://plugins.jetbrains.com/plugin/18409-jetpack-compose)

~~なんかいかにもなプラグインがあったのでインストールします。~~
いやだってサイトにほとんど説明が無いんですもん。
多分プレビュー機能とかがついてくるんだと思います。

安心のJetBrains製

### Android SDK

なんか知らない間にAndroid SDKもGUIからインストール出来るようになってました。
2,3年前にCUIのインストーラでインストールした記憶があるんですが...

設定の

> Appearance & Behavior > System Settings > Android SDK

から必要なバージョンをインストールします。

![Android SDKのインストール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/651da3a4-7601-7231-56d0-45fbff30a1a1.png)

今回は以前8.1(Oreo)をインストールしていたので飛ばしました。

## プロジェクト作成

[新規プロジェクト]から[Android]を選択

![新規プロジェクトテンプレート](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/36e3282e-b9ab-2be8-db53-457f78d59a81.png)

[Empty Activity]を選択して次へ

### プロジェクト設定

![初期化画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/9ef7e7b3-a69b-1583-8d39-a01bc538c562.jpeg)

**ComposeはAPIレベル21 (Android 5.0-Lollipop)からしか対応してない**ので最小バージョンをそれ以上にしておきましょう。

[Use legacy android-support libraries] はオフにしておきます


## build.gradleの編集

### Composeの有効化

app ディレクトリのbuild.gradleに次の文を加えます

```(app) build.gradle
android{
    //以下を追加
    buildFeatures{
        compose=true
    }
    composeOptions{
        kotlinCompilerExtensionVersion '1.1.1'
    }
}
```

これによりCompose機能が有効化されます。これしないと**プレビューとか表示してくれません。** 
ちなみに入力補完は効きませんでした(ビルドは通った)

### 依存関係の追加
同じくapp ディレクトリのbuild.gradleに次の文を加えます

```(app) build.gradle
dependencies{
    //以下を追加
    implementation 'androidx.compose.ui:ui-tooling:1.1.1'
    //こっちは任意
    implementation 'androidx.compose.material:material:1.1.1'
}
```

プロジェクトにComposeへの依存関係が追加されます。
多分 ['androidx.compose.ui:ui-tooling:1.1.1'](https://mvnrepository.com/artifact/androidx.compose.ui/ui-tooling?repo=google) がComposeのコア部分です。
Compose最重要の@Composableなどはここからインポートされます。

## 使ってみる

適当なパッケージ **com.alrexu.composetest.screen** を作って **TestScreen.kt** を作成します。

- com/alrexu/composetest
    - MainActivity.kt
    - screen
        - TestScreen.kt


ひとまずここに**Composable**関数 (後述) を定義していきます。
呼び出せればいいっぽいので実際は割とどこでもいいのかな?
[公式サイト](https://developer.android.com/jetpack/compose/tutorial)では **onCreate()** 内で **setContent()** を呼んでそこに直書きしてますね。

### Hello World!

```TestScreen.kt
package com.alrexu.composetest.screen

import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

class TestScreen {
    @Preview()
    @Composable
    fun testScreen(){
        Text(text = "Hello World")
    }
}
```

ComposeではUIを構築(Compose)する関数は@Composableを付与され**Composable関数**と呼ばれます。
ComposableからComposableを呼び出すことで連鎖的にUIを構築するようです。(testScreen()内のTextもComposable関数)
@Previewが付与されていますが、これによってIDEが対象のComposableのライブプレビューを表示してくれます。

ここでビルドしろって言われたのでビルドします。

![プレビュー1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/b523a2e7-5671-8310-95ec-90a2a8121554.jpeg)

**素晴らしい...**

#### @Preview
@Previewの付いた関数は無引数である必要があります。
引数付きのComposableをプレビューする場合、無引数のプレビュー用関数を作成しそこから呼び出す必要があります。

あと引数に値を渡せばプレビュー設定を弄れるようです。
例えば
```TestScreen.kt
@Preview(widthDp = 100, heightDp = 200)
```
とすればプレビューの幅、高さを指定できます。(Dpは密度非依存ピクセル)

## もう少し弄る

どうやらプレビュー更新のたびにビルドが走るようです。
(Kotlinで書いてるから当たり前っちゃ当たり前)

ボタンを付けてみます。(Button関数を見つけた)
ちょっと思ったけどこれ連続で関数呼び出せば *LinearLayout* みたいになるのでは。
```TestScreen.kt
package com.alrexu.composetest.screen

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview

class TestScreen {
    @Preview(widthDp = 100, heightDp = 200)
    @Composable
    fun testScreen(){
        Text(text = "Goodbye")
        Button(onClick = {}) {
            Text(text = "寝る")
        }
    }
}
```
![プレビュー2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/10f59583-0fb8-6639-2974-2b974eb82ca6.png)

わぉ

### 追加

#### Column()
連続的に配置する場合にはこれで囲むようです。

#### MaterialTheme()
内部がマテリアルデザインになるようです。

以上を加えて、あと見ずらいので文字色を白にしたものがこちらです。

```TestScreen.kt
package com.alrexu.composetest.screen

import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview

class TestScreen {
    @Preview(widthDp = 100, heightDp = 200)
    @Composable
    fun testScreen(){
        MaterialTheme() {
            Column {
                Text(text = "Goodbye", color = Color.White)
                Button(onClick = {}) {
                    Text(text = "寝る")
                }
            }
        }
    }
}
```
![プレビュー3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705544/23eaf7b0-c5bd-02d5-40e1-56015cdb3eb4.png)

**(・∀・)イイネ!!**

## 結論

**Intellij IdeaでもAndroid Composeは使える!**

ググればググるほど面白そうな情報が見つかるのでちょっと今度これでアプリ作ってみようかと思ってます。