Maven Repositoryで公開されたJetpack Composeを触ってみた

Google IO 2019で発表されたJetpack ComposeがMaven Repositoryで公開されたというツイートを見かけたので、ざっくりとコードを書きながらまとめてみた。今までAOSPでソースコードだけが公開されている状態でしたが、Maven Repositoryで公開されたことで気軽に試せるようになりましたね。個人的なメモなので新しい情報はおそらくないと思います。

関連ページ

検証環境

  • Android Studio 3.5.1
  • Android Gradle Plugin 3.5.1
  • Kotlin 1.3.5
  • minSdkVersion 21
  • Android Jetpack
    • Compose
      • androidx.compose:compose-runtime:0.1.0-dev01
      • androidx.compose:compose-compiler:0.1.0-dev01
    • UI
      • androidx.ui:ui-core:0.1.0-dev01:
      • androidx.ui:ui-framework:0.1.0-dev01
      • androidx.ui:ui-text:0.1.0-dev01(テキストを扱う場合)
      • androidx.ui:ui-layout:0.1.0-dev01(レイアウトを扱う場合)

Hello Jetpack Compose

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent { Text("Hello Jetpack Compose") }
  }
}

f:id:yuyakaido:20191014192723p:plain

テキスト

Text

色々とカスタマイズが可能そうです。

@Composable
fun Text(
    text: String,
    modifier: Modifier = Modifier.None,
    style: TextStyle? = null,
    paragraphStyle: ParagraphStyle? = null,
    softWrap: Boolean = DefaultSoftWrap,
    overflow: TextOverflow = DefaultOverflow,
    // TODO(siyamed): remove suppress
    @SuppressLint("AutoBoxing")
    maxLines: Int? = DefaultMaxLines,
    selectionColor: Color = DefaultSelectionColor
) {
    Text(
        text = AnnotatedString(text),
        modifier = modifier,
        style = style,
        paragraphStyle = paragraphStyle,
        softWrap = softWrap,
        overflow = overflow,
        maxLines = maxLines,
        selectionColor = selectionColor
    )
}

TextStyle

TextStyleを利用するとTextViewに生えているようなスタイルの設定が可能そうです。

data class TextStyle(
    val color: Color? = null,
    val fontSize: Sp? = null,
    val fontSizeScale: Float? = null,
    val fontWeight: FontWeight? = null,
    val fontStyle: FontStyle? = null,
    val fontSynthesis: FontSynthesis? = null,
    var fontFamily: FontFamily? = null,
    val fontFeatureSettings: String? = null,
    val letterSpacing: Float? = null,
    val baselineShift: BaselineShift? = null,
    val textGeometricTransform: TextGeometricTransform? = null,
    val localeList: LocaleList? = null,
    val background: Color? = null,
    val decoration: TextDecoration? = null,
    val shadow: Shadow? = null
)

主要なパラメータを設定してみます。

class MainActivity : AppCompatActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      Text(
        text = "Hello Jetpack Compose",
        style = TextStyle(
          color = Color.DarkGray,
          fontSize = 28.sp,
          fontWeight = FontWeight.bold,
          background = Color.LightGray,
          decoration = TextDecoration.Underline
        )
      )
    }
  }
}

f:id:yuyakaido:20191014195138p:plain

Composable

Composableを利用することで独自コンポーネントを定義することが出来ます。

  @Composable
  private fun styledText(text: String) {
    return Text(
      text = text,
      style = TextStyle(
        color = Color.DarkGray,
        fontSize = 20.sp,
        fontWeight = FontWeight.bold
      )
    )
  }

レイアウト

Column

Columnで囲むことで要素を縦に並べることが出来ます。

  @Composable
  private fun textColumns() {
    Column {
      styledText("Column 1")
      styledText("Column 2")
      styledText("Column 3")
    }
  }

f:id:yuyakaido:20191014202214p:plain

Row

Rowで囲むことで要素を横に並べることが出来ます。

  @Composable
  private fun textRows() {
    Row {
      styledText("Column 1")
      styledText("Column 2")
      styledText("Column 3")
    }
  }

f:id:yuyakaido:20191014202229p:plain

Padding

  @Composable
  private fun textWithPadding() {
    Padding(16.dp) {
      styledText("Hello Jetpack Compose")
    }
  }

f:id:yuyakaido:20191014203732p:plain

状態変更

良くある例として、ボタンを押すとインクリメントされていくやつを実装してみます。

  @Composable
  private fun counter() {
    val count = +state { 0 }
    MaterialTheme {
      Column {
        Button(
          text = "Increment",
          onClick = {
            count.value++
          }
        )
        styledText("Count: ${count.value}")
      }
    }
  }

f:id:yuyakaido:20191014211926p:plain

所感

  • 関連情報が少ないのでライブラリ自体のコードを読みながら実装を進める必要がある
  • Androidアプリ開発の経験があれば、大体当たりをつけてコードを書いていけると思う

疑問点

  • リストやグリッドの実装方法
    • コードを眺めてみると、StackやTableといったレイアウトが用意されており、これらを活用すると実装できそうな予感
    • StackがLinearLayoutManagerのような挙動で、TableがGridLayoutManagerのような挙動かな?
  • 内部実装
    • 内部のコードを軽く読んでみたが、どのようにUIが描画されているのかまでは追いきれなかった
    • 既存のWidgetとの互換性はあるのだろうか?そもそもパラダイムが違うのでブリッジは無理?