Compose UI:Surface

投稿日:  更新日:

Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。

そのライブラリ中のSurfaceについて、構成や使用方法などをまとめます。

※環境:Android Studio Flamingo | 2022.2.1
   :androidx.compose.material3:material3:1.1.1
   :androidx.compose.ui:ui:1.4.3

スポンサーリンク

UIの概要

Surfaceは一枚のパネルを表現するUI要素です。

例はアプリの背景として利用されているSurfaceです。

        :
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    /* コンテンツ */
                }
            }
        }
    }
	    :

様々なコンポーネントのバックパネルとして利用される事が多いです。

スポンサーリンク

関数の引数

Surfaceの状態(コンテンツ、装飾、演出など)は、引数により指定できます。

@Composable
@NonRestartableComposable
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    border: BorderStroke? = null,
    content: @Composable () -> Unit
)
引数概要
checkedBooleanチェックの状態:true/false
onCheckedChange(Boolean) -> Unitチェックの変化で実行する関数オブジェクト
selectedBooleanセレクトの状態:true/false
onClick( ) -> Unitクリック、セレクトで実行する関数オブジェクト
enableBooleanUI操作の有効:true/無効:false
※操作:クリック、セレクト、チェック
modifierModifierUI全般の装飾パラメータ
shapeShape角の形状
colorColorコンポーネント(パネル)の色
contentColorColorコンテンツの色
tonalElevationDp色調を変える高さ(高:濃い~低:薄い)
shadowElevationDp影の長さを変える高さ(高:長い~低:短い)
borderBorderStroke輪郭
interactionSourceMutableInteractionSourceユーザが行ったUI操作の観測と報告
content( ) -> Unit内部に配置するコンテンツ

引数の組み合わせにより、4タイプのSurfaceが提供されています。違いはイベント処理関連の引数の有無です。

Surface引数Type1Type2Type3Type4
checked※1
onCheckedChange
selected
onClick
enable
interactionSource
modifier
shape
color
contentColor
tonalElevation
shadowElevation
border
content
※1:イベント処理関連
【用途】
  Type1:アプリ画面の背景
  Type2:Buttonの形状
【特徴】
  Type2,3,4:リップルエフェクト有
スポンサーリンク

関数の構成

SurfaceはComposable関数にBoxを使って、UIの機能を持たせた構成になっています。Boxはインライン関数なので展開されて階層は残りません。

CompositionLocalProviderはCompositionLocalで常用される関数です。これについては後述します。

Surfaceの構成

参考:Surface関数全体(Type1、Surface.ktより抜粋)
@Composable
@NonRestartableComposable
fun Surface(
    modifier: Modifier = Modifier,
    shape: Shape = RectangleShape,
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),
    tonalElevation: Dp = 0.dp,
    shadowElevation: Dp = 0.dp,
    border: BorderStroke? = null,
    content: @Composable () -> Unit
) {
    val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
    CompositionLocalProvider(
        LocalContentColor provides contentColor,
        LocalAbsoluteTonalElevation provides absoluteElevation
    ) {
        Box(
            modifier = modifier
                .surface(
                    shape = shape,
                    backgroundColor = surfaceColorAtElevation(
                        color = color,
                        elevation = absoluteElevation
                    ),
                    border = border,
                    shadowElevation = shadowElevation
                )
                .semantics(mergeDescendants = false) {}
                .pointerInput(Unit) {},
            propagateMinConstraints = true
        ) {
            content()
        }
    }
}
スポンサーリンク

コンポーネントとコンテンツの色

Surfaceを使うと、コンポーネント(パネル)に合わせたコンテンツの色が自動設定されたるようになっています。

カラーシステム

マテリアルデザインにカラーシステムという指針があります。

カラーシステムは色に役割(主役、脇役、など)を持たせています。さらに、役割毎にコンポーネントとコンテンツの色を定義しています。※詳細は「Color system」を参照

カラーシステム

コンポーネントとコンテンツの色は対になる色です。

例えば、アプリの主画面に配置するButtonは、次のような配色になります。

Buttonの配色

このカラーシステムに従った配色はテーマの意図に基づいて決定し、ColorSchemeクラスに格納されます。そして、LocalColorSchemeというCompositionLocal変数で管理されています。

ColorSchemeに格納された色は次のように参照できます。
※MaterialTheme.colorSchemeはColorSchemeクラスのインスタンスを返す

val _primasy = MaterialTheme.colorScheme.primary
val _onPrimasy = MaterialTheme.colorScheme.onPrimary
val _secondary = MaterialTheme.colorScheme.secondary
val _tertiary = MaterialTheme.colorScheme.tertiary
val _background = MaterialTheme.colorScheme.background
val _error = MaterialTheme.colorScheme.error
val _surface = MaterialTheme.colorScheme.surface
    :
	:

色の自動設定

Surfaceは引数colorへコンポーネントの色を指定すると、初期値付き引数の動作により、引数contentColorへコンテンツの色が設定されるようになっています。

colorはそのままパネルの色として利用されます。

contentColorはLocalContentColorというCompositionLocal変数へ格納されて、Surface階下のUIツリーをスコープに持つ変数になります。これを行っているのがCompositionLocalProvider( )です。

※CompositionLocalについては「」を参照

@Composable
@NonRestartableComposable
fun Surface(
    ...
    color: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = contentColorFor(color),	// 対になる色を返す
    tonalElevation: Dp = 0.dp,
    ...
) {
    val absoluteElevation = LocalAbsoluteTonalElevation.current + tonalElevation
    CompositionLocalProvider(	// スコープの指定
        LocalContentColor provides contentColor,
        LocalAbsoluteTonalElevation provides absoluteElevation
    ) {
        Box(...) {		//  ↑
            content()	// CompositionLocal変数のスコープ範囲
        }				//  ↓
    }
}

例:Surface上のText

Surface上のTextを例にして、コンポーネントとコンテンツの色の扱われ方を示します。

Surfaceはcolorに指定された色(background)の対になる色(onBackground)をLocalContentColorへ設定します。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyApplicationTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    Text(text = "Hello World !!", fontSize = 32.sp)
                }
            }
        }
    }
}

Textは引数colorを指定しない場合、LocalContentColorから描画する色を取得します(ハイライト部分)。

@Composable
fun Text(
    text: String,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    ...,
    style: TextStyle = LocalTextStyle.current
) {

    val textColor = color.takeOrElse {
        style.color.takeOrElse {
            LocalContentColor.current
        }
    }
    // NOTE(text-perf-review): It might be worthwhile writing a bespoke merge implementation that
    // will avoid reallocating if all of the options here are the defaults
    val mergedStyle = style.merge(
        TextStyle(
            color = textColor,
            ...
        )
    )
    BasicText(
        text,
        modifier,
        mergedStyle,
        onTextLayout,
        overflow,
        softWrap,
        maxLines,
    )
}

その結果、カラーシステムの指針に沿った配色の画面が出力されます。

例:Surface上のText

スポンサーリンク

関連記事:

Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のButtonについて、構成や使用方法などをまとめます。 ※環境:Android Studio Flamingo | 2022.2.1    :androidx.compose.material3:material3:1.1.1    :androidx.compose.ui:ui:1.4.3 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のRadioButtonについて、構成や使用方法などをまとめます。 ※環境:Android Studio Hedgehog | 2023.1.1     Kotlin 1.8.10     Compose Compiler 1.4.3 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中にUI要素を格納する機能をもつコンテナ型のUIがあります。 Column/Row/Boxがコンテナ型のUIです。構成や使用方法などをまとめます。 ※環境:Android Studio Hedgehog | 2023.1.1 Patch 1     Kotlin 1.8.10     Compose Compiler 1.4.3 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のImageについて、構成や使用方法などをまとめます。 ※環境:Android Studio Hedgehog | 2023.1.1 Patch 2     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation 1.5.0 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のDividerについて、構成や使用方法などをまとめます。 ※環境:Android Studio Hedgehog | 2023.1.1 Patch 2     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.material3:material3 1.1.1 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のSpacerについて、構成や使用方法などをまとめます。 ※環境:Android Studio Hedgehog | 2023.1.1 Patch 2     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.foundation 1.5.0 ...
Jetpack composeは、アプリ開発に必要な一通りのUIコンポーネントをライブラリで提供しています。 そのライブラリ中のSliderについて、構成や使用方法などをまとめます。 ※環境:Android Studio Hedgehog | 2023.1.1 Patch 2     Kotlin 1.9.0     Compose Compiler 1.5.1     androidx.compose.material3:material3 1.1.1 ...
スポンサーリンク