Jetpack Composeで背景色をグラデーションさせたい

この記事をシェア
JetpackCompose一問一答

コンポーネントの背景色をグラデーションさせる方法を紹介します。いちいちXMLを作成しなくて済むのが本当にありがたいです。

やりたいこと

コンポーネントの背景にグラデーションを設定します。

環境

以下の環境で確認しています。

  • Kotlin 1.6.10
  • Jetpack Compose 1.1.1

Modifier.background()

コンポーネントの背景はModifier.background()で設定できます。Modifier.background()のシグネチャは2種類あって、Colorを引数にとるタイプと、Brushを引数にとるタイプがあります。背景をグラデーションさせる場合は、Brushを引数にとる方を使います。

fun Modifier!.background(
    brush: Brush!,
    shape: Shape! = RectangleShape,
    alpha: Float! = 1.0f
): Modifier

Colorは分かりやすいけど、Brushって何?と思うかもしれません。

Brush

Brush(ブラシ)は塗りつぶし方法の指定するクラスです。ペイントソフトなどの塗りつぶしのアイコンがブラシの絵になっているのを想像すると、イメージがつきやすいと思います。

Brushクラスには、いろいろなグラデーションのBrushを作成するCompanion functionが用意されています。これらは、Brushのサブクラスのグラデーションクラスオブジェクトを返すので、Modifier.background()に指定することで、コンポーネントの背景をグラデーションさせることができます。

ではまず基本的な5種類のグラデーションを見ていきます。

verticalGradient

Box(
    modifier = Modifier
        .background(Brush.verticalGradient(
            colors = listOf(Color.Red, Color.Yellow)
        )),
    contentAlignment = Alignment.Center,
) {
    Text("verticalGradient")
}

Brush.verticalGradient()は、縦方向に色が変化するグラデーションを作成します。

colors引数には、Colorのリストを指定します。これは他の種類のグラデーションでも同様です。

horizontalGradient

Box(
    modifier = Modifier
        .background(Brush.horizontalGradient(
            colors = listOf(Color.Red, Color.Yellow)
        )),
    contentAlignment = Alignment.Center,
) {
    Text("horizontalGradient")
}

Brush.horizontalGradient()は、横方向に色が変化するグラデーションを作成します。

linearGradient

Box(
    modifier = Modifier
        .background(Brush.linearGradient(
            colors = listOf(Color.Red, Color.Yellow)
        )),
    contentAlignment = Alignment.Center,
) {
    Text("linearGradient")
}

Brush.linearGradient()は、始点から終点に向かって真っすぐに色が変化していくグラデーションを作成します。デフォルトでは左上から右下に向かって変化します。上から下に変化するように指定するとverticalGradientと同じに、左から右に変化するように指定するとhorizontalGradientと同じになります。

Box(
    modifier = Modifier
        .background(Brush.linearGradient(
            colors = listOf(Color.Red, Color.Yellow),
            start = Offset(x = 0f, y = Float.POSITIVE_INFINITY),
            end = Offset(x = Float.POSITIVE_INFINITY, y = 0f),
        )),
    contentAlignment = Alignment.Center,
) {
    Text("linearGradient")
}

始点と終点はOffsetで指定します。この例では始点を左下に、終点を右上に設定しています。最初の例と見比べると、グラデーションの向きが変わっていることが分かります。

radialGradient

Box(
    modifier = Modifier
        .background(Brush.radialGradient(
            colors = listOf(Color.Red, Color.Yellow)
        )),
    contentAlignment = Alignment.Center,
) {
    Text("radialGradient")
}

Brush.radialGradient()は、中心から放射状に色が変化するグラデーションを作成します。center引数でグラデーションの中心点を指定できます。

sweepGradient

Box(
    modifier = Modifier
        .background(Brush.sweepGradient(
            colors = listOf(Color.Red, Color.Yellow)
        )),
    contentAlignment = Alignment.Center,
) {
    Text("sweepGradient")
}

Brush.sweepGradient()は、時計の3時方向から時計回りにぐるっと一周かけて色が変化するグラデーションです。こちらもradialGradientと同じように、center引数で中心点を指定できます。

いろいろなバリエーション

色の数を増やす

Box(
    modifier = Modifier
        .background(Brush.horizontalGradient(
            colors = listOf(Color.Blue, Color.White, Color.Red)
        )),
    contentAlignment = Alignment.Center,
) {
}

colors引数はListなので、色の数は2色に限定されません。この例では3色を指定しています。色数を増やすことによって、色の変化を細かく指定することもできます。

繰り返し

Box(
    modifier = Modifier
        .background(Brush.horizontalGradient(
            colors = listOf(Color.Red, Color.Yellow),
            startX = 0f,
            endX = 100f,
            tileMode = TileMode.Mirror,
        )),
    contentAlignment = Alignment.Center,
) {
}

tileModeを指定すると、グラデーションパターンを繰り返すことができます。horizontalGradientverticalGradientlinearGradientの場合は、グラデーションの開始・終了位置がコンポーネントのサイズよりも小さくなるようにstartendを指定し、tileModeTileMode.RepeatedまたはTileMode.Mirrorを指定します。Repeatedは単純な繰り返しなので、始点と終点の色が違うと、不連続になります。Repeatedは反転して繰り返すので、継ぎ目なく色の変化が繰り返されます。

Box(
    modifier = Modifier
        .background(Brush.radialGradient(
            colors = listOf(Color.Red, Color.Yellow),
            radius = 100f,
            tileMode = TileMode.Repeated,
        )),
    contentAlignment = Alignment.Center,
) {
}
JetpackCompose一問一答

Jetpack Compose一問一答

コンテンツは随時追加していきます。

この記事をシェア