Slide 1

Slide 1 text

Jetpack Compose Modifier 徹底解説 @wiroha Copyright © ZOZO, Inc. 1

Slide 2

Slide 2 text

© ZOZO, Inc. 株式会社ZOZO 技術本部 技術戦略部 DevRelブロック @wiroha(ゐろは) バックエンドエンジニア、PM、Androidエンジニアな どを経て現職のDevRelへ。 イベントの運営、文章を書くことが好き。 2

Slide 3

Slide 3 text

© ZOZO, Inc. 3 目次 ● 導入・概要 ● プロダクトコードおけるModifierの使用頻度集計 ● Modifier解説 - 全47種 ● 使用回数 総合ランキング

Slide 4

Slide 4 text

© ZOZO, Inc. 4 目次 ● 導入・概要 ● プロダクトコードおけるModifierの使用頻度集計 ● Modifier解説 - 全47種 ● 使用回数 総合ランキング

Slide 5

Slide 5 text

© ZOZO, Inc. 5 導入・概要 ● Jetpack Composeを用いたUI開発において、Modifierは欠かせない要素です。 Composableの外観、レイアウト、動作などを変更するために使います。 ● しかし、普段使わないModifierは知らない方も多いのではないでしょうか? ● 本セッションでは、Jetpack ComposeのModifier約150種類の中から、時間の許す限り解説しま す! Text( text = "padding 32dp", modifier = Modifier.padding(32.dp) )

Slide 6

Slide 6 text

© ZOZO, Inc. 6 導入・概要 ● 具体的なコード例に加え、画像・アニメーションを用いて視覚的にわかりやすく解説します。 公式ドキュメントの文章を読むだけではピンと来ない内容も、直感的に理解できるはずです。 引用元 https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier#(androidx.compose.ui.Modifier).alpha(kotlin.Float) Icon( imageVector = Icons.Filled.Favorite, modifier = Modifier.alpha(0.5f) )

Slide 7

Slide 7 text

© ZOZO, Inc. 7 目次 ● 導入・概要 ● プロダクトコードおけるModifierの使用頻度集計 ● Modifier解説 - 全47種 ● 使用回数 総合ランキング

Slide 8

Slide 8 text

© ZOZO, Inc. 8 カテゴリごとのModifierの一覧 公式ドキュメント「Compose 修飾子のリスト」ページより。 カテゴリ名 日本語訳 種類数 カテゴリ名 日本語訳 種類数 Action 操作 11 Padding パディング 16 Alignment 位置揃え 3 Pointer ポインタ 4 Animation アニメーション 2 Position 位置 3 Border 枠線 1 Semantics セマンティクス 4 Drawing 描画 12 Scroll スクロール 11 Focus フォーカス 9 Size サイズ 33 Graphics グラフィック 2 Testing テスト 1 Keyboard キーボード 2 Transformations 変換 3 Layout レイアウト 3 Other その他 27

Slide 9

Slide 9 text

たくさんある!! ピックアップ時の参考用に ZOZOのプロダクトコードでの使用頻度を集計

Slide 10

Slide 10 text

© ZOZO, Inc. https://zozo.jp/ 10 ● ファッションEC ● 1,600以上のショップ、9,000以上のブランドの取り扱い ● 常時102万点以上の商品アイテム数と毎日平均2,600点以上の新着 商品を掲載(2024年6月末時点) ● ブランド古着のファッションゾーン「ZOZOUSED」や コスメ専門モール「ZOZOCOSME」、靴の専門モール 「ZOZOSHOES」、ラグジュアリー&デザイナーズゾーン 「ZOZOVILLA」を展開 ● 即日配送サービス ● ギフトラッピングサービス ● ツケ払い など

Slide 11

Slide 11 text

© ZOZO, Inc. https://wear.jp/ 11 ● あなたの「似合う」が探せるファッションコーディネートアプリ ● 1,700万ダウンロード突破、コーディネート投稿総数は1,400万 件以上(2024年6月末時点) ● コーディネートや最新トレンド、メイクなど豊富なファッション 情報をチェック ● AIを活用したファッションジャンル診断や、フルメイクをARで試 せる「WEARお試しメイク」を提供 ● コーディネート着用アイテムを公式サイトで購入可能 ● WEAR公認の人気ユーザーをWEARISTAと認定。モデル・タレン ト・デザイナー・インフルエンサーといった各界著名人も参加

Slide 12

Slide 12 text

● ショップスタッフの販売サポートツール ● ブランド自社ECやZOZOTOWNなどの複数チャネルに、無料で コーディネート画像の同時投稿が可能。さらに、投稿したコー ディネート経由のEC売上や送客数、コーディネートの閲覧数な ど、オンライン上での成果を可視化。 ● ZOZOTOWN上で実店舗の在庫取り置きを希望したお客様への 対応を、ショップスタッフ様がFAANS上の簡単操作で完結。

Slide 13

Slide 13 text

© ZOZO, Inc. 13 各Androidアプリの情報 ● ZOZOTOWN ○ 2012年5月 リリース ○ 2021年6月 Jetpack Compose導入 ● WEAR ○ 2013年10月 リリース ○ 2024年5月 フルリニューアル ○ 2022年4月 Jetpack Compose導入 ● FAANS ○ 2022年7月 リリース ○ 2021年8月 Jetpack Compose導入(リリース前 開発中)

Slide 14

Slide 14 text

© ZOZO, Inc. 14 プロダクトコードで使用されているModifier カテゴリ名 日本語訳 使用数/種類数 カテゴリ名 日本語訳 使用数/種類数 Action 操作 4/11 Padding パディング 6/16 Alignment 位置揃え 3/3 Pointer ポインタ 1/4 Animation アニメーション 1/2 Position 位置 2/3 Border 枠線 1/1 Semantics セマンティクス 0/4 Drawing 描画 6/12 Scroll スクロール 4/11 Focus フォーカス 4/9 Size サイズ 21/33 Graphics グラフィック 1/2 Testing テスト 1/1 Keyboard キーボード 0/2 Transformations 変換 2/3 Layout レイアウト 2/3 Other その他 5/27 よく使われていて面白そうなカテゴリ、使われていないが注目したいカテゴリから紹介

Slide 15

Slide 15 text

© ZOZO, Inc. 15 目次 ● 導入・概要 ● プロダクトコードおけるModifierの使用頻度集計 ● Modifier解説 - 全47種 ● 使用回数 総合ランキング

Slide 16

Slide 16 text

Action 操作 1. clickable 2. draggable 3. selectable 4. combinedClickable 5. draggable2D 6. selectableGroup 7. toggleable 8. triStateToggleable

Slide 17

Slide 17 text

© ZOZO, Inc. 1. clickable 17 クリックやタップなどのタッチイベントを検出できるようにします。 val count = remember { mutableStateOf(0) } Text( text = "Clicked count: ${count.value}", modifier = Modifier.clickable { count.value += 1 } ) Action

Slide 18

Slide 18 text

© ZOZO, Inc. 2. draggable 18 単一のOrientation(水平または垂直)でドラッグします。 var offsetX by remember { mutableStateOf(0f) } val draggableState = rememberDraggableState { delta -> offsetX += delta } Box( modifier = Modifier .offset(x = offsetX.dp) .size(100.dp) .background(Color.Blue) .draggable( orientation = Orientation.Horizontal, state = draggableState ) ) Action

Slide 19

Slide 19 text

© ZOZO, Inc. var selected by remember { mutableStateOf(false) } Row { Text( "Option 1", modifier = Modifier .selectable(selected = selected, onClick = { selected = true }) .background( if (selected) Color.Gray else Color.White ) ) Text( "Option 2", modifier = Modifier .selectable(selected = !selected, onClick = { selected = false }) .background( if (!selected) Color.Gray else Color.White ))} 3. selectable 19 項目の選択状態を管理できるようにします。 ラジオボタンやチェックボックスのような動作を実現できます。 Action

Slide 20

Slide 20 text

© ZOZO, Inc. 4. combinedClickable 20 クリック、ダブルクリック、長押しといった複数のタッチイベントを1 つのComposableで処理できるようにします。 var message by remember { mutableStateOf("") } Box( modifier = Modifier .size(200.dp).background(Color.LightGray) .combinedClickable( onClick = { message = "Clicked!" }, onDoubleClick = { message = "Double Clicked!" }, onLongClick = { message = "Long Clicked!" }, interactionSource = remember { MutableInteractionSource() }, indication = null ), contentAlignment = Alignment.Center ) { Text(message) } Action

Slide 21

Slide 21 text

© ZOZO, Inc. 5. draggable2D 21 コンポーザブルを2次元平面(水平と垂直の両方)でドラッグします。 var offsetX by remember { mutableStateOf(0f) } var offsetY by remember { mutableStateOf(0f) } val state = rememberDraggable2DState { delta -> offsetX += delta.x offsetY += delta.y } Box( modifier = Modifier .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) } .size(100.dp) .background(Color.Blue) .draggable2D(state) ) Action

Slide 22

Slide 22 text

© ZOZO, Inc. 6. selectableGroup 22 複数の項目から一つだけを選択できるグループを作成します。 Column(Modifier.selectableGroup()) { options.forEach { option -> Row( Modifier.fillMaxWidth().height(56.dp) .selectable( selected = (option == selectedOption), onClick = { selectedOption = option } ) .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically ) { RadioButton( selected = (option == selectedOption), onClick = null ) Text( text = option, modifier = Modifier.padding(start = 16.dp) ) }} Action

Slide 23

Slide 23 text

© ZOZO, Inc. 7. toggleable 23 入力イベント・ユーザー補助イベントを介して切り替え可能にします。 var checkedState by remember { mutableStateOf(false) } Row( modifier = Modifier.fillMaxWidth().padding(16.dp), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier.size(24.dp) .background( color = if (checkedState) Color.Blue else Color.LightGray) .toggleable( value = checkedState, onValueChange = { checkedState = it }, role = Role.Checkbox ) ) Spacer(modifier = Modifier.width(8.dp)) Text(text = if (checkedState) "On" else "Off") } Action

Slide 24

Slide 24 text

© ZOZO, Inc. 8. triStateToggleable 24 入力イベント・ユーザー補助イベントを介して「オン」「オフ」「不確定」 の3つの状態の間で切り替え可能にします。 .background( color = when (state) { ToggleableState.On -> Color.Black ToggleableState.Off -> Color.White ToggleableState.Indeterminate -> Color.Gray } ) .triStateToggleable( state = state, onClick = { state = when (state) { ToggleableState.On -> ToggleableState.Indeterminate ToggleableState.Indeterminate -> ToggleableState.Off ToggleableState.Off -> ToggleableState.On } } ) Action

Slide 25

Slide 25 text

Alignment 位置揃え 1. align 2. alignByBaseline

Slide 26

Slide 26 text

© ZOZO, Inc. 1. align 26 指定の方向に揃えます。Column, Row, Box内で使用できます。 Row (modifier = Modifier .height(150.dp) .background(Color.LightGray)) { Text( "Top", modifier = Modifier.align(Alignment.Top) ) Text( "Bottom", modifier = Modifier.align(Alignment.Bottom) ) Text( "CenterVertically", modifier = Modifier.align(Alignment.CenterVertically) ) } Alignment

Slide 27

Slide 27 text

© ZOZO, Inc. 2. alignByBaseline 27 RowやColumn内でComposableのベースラインを揃えます。 Row { Text( text = "24spのテキスト", fontSize = 24.sp, modifier = Modifier.alignByBaseline() ) Text( text = "16spのテキスト", fontSize = 16.sp, modifier = Modifier.alignByBaseline() ) } Alignment alignByBaseline指定なしの場合 WEARアプリ内「コーデ予報」で、気温と”℃”をベースライン揃え

Slide 28

Slide 28 text

Border 枠線 1. border

Slide 29

Slide 29 text

© ZOZO, Inc. 枠線 1. border 29 Composableに枠線を追加します。枠線の太さ、色、形状などを指定できます。 Box( modifier = Modifier .size(100.dp) .border(width = 2.dp, color = Color.Black) ) Border Box( modifier = Modifier .size(100.dp) .border( width = 2.dp, color = Color.Red, shape = RoundedCornerShape(16.dp) ) )

Slide 30

Slide 30 text

Drawing 描画 1. background 2. clip 3. alpha 4. zIndex 5. clipToBounds 6. shadow 7. drawBehind

Slide 31

Slide 31 text

© ZOZO, Inc. 1. background 31 背景に色、グラデーション、画像を設定します。 Box(modifier = Modifier.height(80.dp).width(300.dp) .background(Color.Cyan) ) { Text("background(Color.Cyan)") } Drawing .background( brush = Brush.verticalGradient( colors = listOf(Color.Transparent, Color.Gray) ) )

Slide 32

Slide 32 text

© ZOZO, Inc. 2. clip 32 Composableの描画範囲を指定した形状に切り抜きます。 Box( modifier = Modifier.size(100.dp, 50.dp) .clip(RoundedCornerShape(16.dp)) .background(Color.Red) ) Drawing Box( modifier = Modifier.size(100.dp, 50.dp) .clip(CutCornerShape(topStart = 20.dp)) .background(Color.Blue) )

Slide 33

Slide 33 text

© ZOZO, Inc. 3. alpha 33 0.0f (透明) から 1.0f (不透明) までの値で透明度を指定します。 Icon( imageVector = Icons.Filled.Favorite, contentDescription = "Favorite Icon with Alpha", modifier = Modifier .size(48.dp) .alpha(0.5f) ) Drawing alpha指定なしの場合

Slide 34

Slide 34 text

© ZOZO, Inc. 4. zIndex 34 同じ親レイアウトの子の描画順序を制御し、zIndex値が大きい要素を手前に描画します。 レイアウトにzIndexが適用されていない場合の、デフォルトのzIndex値は0です。 Box { Box( modifier = Modifier .size(100.dp) .background(Color.Red) .zIndex(1f) // 赤いBoxを上に表示 ) Box( modifier = Modifier .size(150.dp) .background(Color.Blue) ) } Drawing

Slide 35

Slide 35 text

© ZOZO, Inc. 5. clipToBounds 35 Composableの子要素が親要素の境界からはみ出さないように切り取ります。 子要素が親要素の範囲外に描画されるのを防ぎたい場合に使用します。 Box( modifier = Modifier .size(200.dp) .background(Color.Gray) .clipToBounds() ) { Box( modifier = Modifier .size(300.dp) .offset(50.dp, 50.dp) .background(Color.Red, shape = CircleShape) ) } Drawing

Slide 36

Slide 36 text

© ZOZO, Inc. 6. shadow 36 影を描画する graphicsLayer を作成します。 影の色、形状などを指定できます。 Box( modifier = Modifier .height(100.dp) .width(100.dp) .shadow(elevation = 8.dp) .background(Color.White) ) Drawing .shadow( elevation = 16.dp, shape = RoundedCornerShape(16.dp), spotColor = Color.Blue ) .background(Color.White)

Slide 37

Slide 37 text

© ZOZO, Inc. 7. drawBehind 37 要素の背後にカスタム描画を行います。線を描画するdrawLine、円を描画するdrawCircle、テキスト を描画するdrawTextなど様々な描画関数が用意されています。 Box( modifier = Modifier.size(150.dp, 100.dp) .background(Color.Gray) .drawBehind { drawLine( color = Color.Cyan, start = Offset(size.width, 0f), // 右上 end = Offset(0f, size.height), // 左下 strokeWidth = 4.dp.toPx() // 線の太さ ) } ) { Text( text = ".drawBehindの例", modifier = Modifier.align(Alignment.Center), color = Color.White ) } Drawing

Slide 38

Slide 38 text

Padding パディング 1. padding 2. paddingFromBaseline

Slide 39

Slide 39 text

© ZOZO, Inc. 1. padding 39 コンテンツの端にスペースを追加します。 引数にはall, paddingValues, 各方向などを指定できます。 Text( text = "padding 32dp", modifier = Modifier.padding(32.dp) ) Padding

Slide 40

Slide 40 text

© ZOZO, Inc. 2. paddingFromBaseline 40 要素のベースラインからのパディングを指定します。 Text( text = "paddingFromBaseLine", modifier = Modifier .paddingFromBaseline(top = 24.dp) ) Padding 引用元 https://developer.android.com/develop/ui/compose/layouts/custom?hl=ja

Slide 41

Slide 41 text

© ZOZO, Inc. Padding その他 41 ● paddingFrom ● absolutePadding ● captionBarPadding ● displayCutoutPadding ● imePadding ● mandatorySystemGesturesPadding ● navigationBarsPadding Padding ● safeContentPadding ● safeGesturesPadding ● statusBarsPadding ● systemBarsPadding ● systemGesturesPadding ● waterfallPadding ● windowInsetsPadding 切り欠きやIMEなど、デバイスの形やシステムUIなどに対応するPaddingが多い。

Slide 42

Slide 42 text

Pointer ポインタ 1. pointerInput

Slide 43

Slide 43 text

© ZOZO, Inc. 1. pointerInput 43 Composableでタッチやマウスなどのポインターイベントを処理するための低レベルのModifierです。 ドラッグ、タップ、ズームなどのカスタムジェスチャーを実装する際に使用します。 var isPressed by remember { mutableStateOf(false) } Box( Modifier .background( if (isPressed) Color.Blue else Color.DarkGray ) .size(100.dp) .pointerInput(Unit) { detectTapGestures( onPress = { isPressed = true tryAwaitRelease() isPressed = false }) } ) Pointer

Slide 44

Slide 44 text

Semantics セマンティクス 1. semantics 2. clearAndSetSemantics 3. progressSemantics

Slide 45

Slide 45 text

© ZOZO, Inc. 1. semantics 45 テストやユーザー補助機能などで使用するために、セマンティクスの Key-Valueペアをレイアウトノードに追加します。 Text( text = "semantics text", modifier = Modifier.semantics { stateDescription = "textのstateはvisibleです" contentDescription = "semantics textというテキストです" } ) Semantics ※動画から音声が流れます

Slide 46

Slide 46 text

© ZOZO, Inc. 2. clearAndSetSemantics 46 コンポーザブルとその子要素の既存のセマンティクス情報をクリア し、 新しいセマンティクス情報を設定します。 Column(modifier = Modifier.clearAndSetSemantics { contentDescription = "全体のcontentDescriptionです" }) { Text(text = "Text 1", modifier = Modifier.semantics { contentDescription = "Text 1" }) Text(text = "Text 2", modifier = Modifier.semantics { contentDescription = "Text 2" }) } Semantics ※動画から音声が流れます

Slide 47

Slide 47 text

© ZOZO, Inc. 3. progressSemantics 47 スクリーンリーダーなどのアクセシビリティツールが、進行状況インジケーターの現在の進行状況を ユーザーに伝えることができます。 "50% 進行状況バー" のように読み上げます。 var progress by remember { mutableStateOf(0.5f) } Column { Text("Downloading...") LinearProgressIndicator( progress = progress, modifier = Modifier.progressSemantics(progress) ) } Semantics ※動画から音声が流れます

Slide 48

Slide 48 text

Size サイズ 1. height, width 2. fillMaxHeight, fillMaxWidth 3. size 4. fillMaxSize 5. aspectRatio 6. wrapContentHeight, wrapContentWidth 7. wrapContentSize 8. defaultMinSize 9. heightIn, widthIn 10. animateContentSize

Slide 49

Slide 49 text

© ZOZO, Inc. 1. height, width 49 高さ、幅を指定します。 Box( modifier = Modifier .height(48.dp) .width(256.dp) .background(Color.LightGray) ) { Text("height(48.dp) width(256.dp)") } Size

Slide 50

Slide 50 text

© ZOZO, Inc. 2. fillMaxHeight, fillMaxWidth 50 要素の高さ・幅を親レイアウトに対して指定した割合で広げます。 引数のfractionに0から1の値を渡すことで、親レイアウトの何割にするか指定できます。 Box( modifier = Modifier .fillMaxWidth() .height(100.dp) .background(Color.LightGray) ) { Text("fillMaxWidth()") } Size .fillMaxWidth(0.5f) // 親の50%に設定

Slide 51

Slide 51 text

© ZOZO, Inc. 3. size 51 要素の幅と高さを指定します。 Box( modifier = Modifier .size(width = 200.dp, height = 100.dp) .background(Color.LightGray) ) { Text("size(width = 200.dp, height = 100.dp)") } Size

Slide 52

Slide 52 text

© ZOZO, Inc. 4. fillMaxSize 52 要素の高さ・幅を親レイアウトに対して指定した割合で広げます。 引数のfractionに0から1の値を渡すことで、親レイアウトの何割にする か指定できます。 Box( modifier = Modifier .fillMaxSize() .background(Color.LightGray) ) { Text("fillMaxSize()") } Size

Slide 53

Slide 53 text

© ZOZO, Inc. 5. aspectRatio 53 要素のアスペクト比(幅と高さの比率) を指定します。 Box( modifier = Modifier .aspectRatio(16f / 9f) .background(Color.LightGray) .fillMaxWidth() ) { Text("aspectRatio(16f / 9f)") } Size

Slide 54

Slide 54 text

© ZOZO, Inc. 6. wrapContentHeight, wrapContentWidth 54 要素の内容が収まる最小限の高さ・幅で表示します。 Column( modifier = Modifier .wrapContentHeight() .background(Color.LightGray) ) { Text("wrapContentHeight()") Text("コンテンツに合わせて高さが調整されます。 長い文だと高さが伸びます。") } Size

Slide 55

Slide 55 text

© ZOZO, Inc. 7. wrapContentSize 55 要素の内容が収まる最小限のサイズで表示します。 Column( modifier = Modifier .wrapContentSize() .background(Color.LightGray) ) { Text("wrapContentSize()") Text("コンテンツに合わせて高さ・幅が調整されま す。長い文だと高さ・幅が伸びます。") } Size

Slide 56

Slide 56 text

© ZOZO, Inc. 8. defaultMinSize 56 要素の最小サイズを指定します。 Box( modifier = Modifier .defaultMinSize(minWidth = 100.dp, minHeight = 50.dp) .background(Color.LightGray) ) { Text("Short Text") } Size Box( modifier = Modifier .defaultMinSize(minWidth = 100.dp, minHeight = 50.dp) .background(Color.LightGray) ) { Text("This is a longer text that exceeds the minimum size.") }

Slide 57

Slide 57 text

© ZOZO, Inc. 9. heightIn, widthIn 57 コンテンツの高さ・幅をmin dpからmax dpの範囲に制限します。 画像の場合、アスペクト比を維持したまま縮小します。minより小さい場合でも拡大はされません。 縮小ではなくトリミングしたい場合はclip Modifierを使います。 Image( painter = painterResource(id = R.drawable.icon_wiroha), contentDescription = "heightIn image", modifier = Modifier.heightIn(min = 50.dp, max = 100.dp) ) Size // heightIn指定なし Image( painter = painterResource(id = R.drawable.icon_wiroha), contentDescription = "normal image", )

Slide 58

Slide 58 text

© ZOZO, Inc. 10. animateContentSize 58 要素のサイズ変更をアニメーションによって滑らかに変化させます。 var expanded by remember { mutableStateOf(false) } Box( modifier = Modifier .animateContentSize() .background(Color.LightGray) .padding(16.dp) .clickable { expanded = !expanded } ) { Text( text = if (expanded) { "コンテンツサイズ変更時にアニメーションするModifierです。 DroidKaigi 2023で発表した「よく見るあのUIをJetpack_Composeで実装する方 法〇選」のアコーディオンでも使っていました。" } else { ".animateContentSize" })} Size

Slide 59

Slide 59 text

Test テスト 1. testTag

Slide 60

Slide 60 text

© ZOZO, Inc. 1. testTag 60 Composableにテスト用のタグを付けます。 UIテストを行う際に、このタグを使って特定のComposableを識別できます。 Text( text = "testTag example", modifier = Modifier.testTag("myText") ) Test @get:Rule val composeTestRule = createComposeRule() @Test fun testTextExists() { composeTestRule.setContent { TestTagExample() } composeTestRule.onNodeWithTag("myText") .assertExists() }

Slide 61

Slide 61 text

Transformations 変換 1. rotate 2. scale 3. transformable

Slide 62

Slide 62 text

© ZOZO, Inc. 1. rotate 62 要素を指定した角度で回転させます。 値を増やすと時計回り、負の数にすると反時計回りで回転させます。 Box( modifier = Modifier .size(100.dp) .rotate(30f) .background(Color.Blue) ) Transformations Text( text = "Hello, world!", modifier = Modifier.rotate(-15f) )

Slide 63

Slide 63 text

© ZOZO, Inc. 2. scale 63 要素を指定した倍率で拡大・縮小します。 Text( text = "Hello, world!", modifier = Modifier .scale(scaleX = 1.5f, scaleY = 3f) .background(Color.LightGray) ) Transformations // scale指定なし Text( text = "Hello, world!", modifier = Modifier .background(Color.LightGray) )

Slide 64

Slide 64 text

© ZOZO, Inc. 3. transformable 64 ユーザーのジェスチャー (ピンチイン/アウト、回転など) に応じて Composableのサイズや回転を変更できるようにします。 var scale by remember { mutableStateOf(1f) } Image( painter = painterResource(id = R.drawable.icon_wiroha), contentDescription = "Transformable Image", modifier = Modifier .fillMaxSize() .transformable( state = rememberTransformableState { zoomChange, _, _ -> scale *= zoomChange }) .scale(scale) ) Transformations

Slide 65

Slide 65 text

Other その他 1. basicMarquee 2. blur 3. hoverable 4. magnifier 5. onPlaced 6. placeholder 7. placeholderShimmer

Slide 66

Slide 66 text

© ZOZO, Inc. 1. basicMarquee 66 幅が広すぎて利用可能なスペースに収まらない場合、コンテンツにマーキーアニメーションを適用します。 iterations, animationMode, delayMillisなどの設定ができます。 Box( modifier = Modifier.fillMaxWidth() ) { Text( ".basicMarquee このように長いテキストだっ た場合にMarqueeで文字が流れます!!!", modifier = Modifier.basicMarquee() ) } Other

Slide 67

Slide 67 text

© ZOZO, Inc. 2. blur 67 要素にぼかし効果を適用します。 radiusX, radiusYでぼかしの半径を指定します。値が大きいほどぼかしが強くなります。 ※Android 12 (API レベル 31) 以降で利用可能です。 val image = painterResource(id = R.drawable.icon_wiroha) Image( painter = image, contentDescription = "Blurred Image", modifier = Modifier .blur( radiusX = 5.dp, radiusY = 30.dp, edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)) ) ) Other

Slide 68

Slide 68 text

© ZOZO, Inc. 3. hoverable 68 要素にマウスホバーなどのホバーインタラクションを追加にします。 マウス接続、Chromebookなどで使用します。 エミュレータではタッチイベントしかサポートされていないため、hoverableは動作しません。 Box( modifier = Modifier .size(64.dp) .background(if (isHovered) Color.Red else Color.Blue) .hoverable(interactionSource = interactionSource), contentAlignment = Alignment.Center ) { Text(if (isHovered) "Hovered" else "Unhovered", color = Color.White) } Other

Slide 69

Slide 69 text

© ZOZO, Inc. 4. magnifier 69 拡大鏡機能を追加します。 ※Android 9 (API レベル 28) 以降で利用できます。 Box( Modifier .magnifier( sourceCenter = { magnifierCenter }, zoom = 2.5f ) .pointerInput(Unit) { detectDragGestures( onDragStart = { magnifierCenter = it }, onDrag = { _, delta -> magnifierCenter += delta }, onDragEnd = { magnifierCenter = Offset.Unspecified }, onDragCancel = { magnifierCenter = Offset.Unspecified } )} .drawBehind { for (diameter in 2 until size.maxDimension.toInt() step 10) { drawCircle( color = Color.Black, radius = diameter / 2f, style = Stroke() )}}) Other

Slide 70

Slide 70 text

© ZOZO, Inc. 5. onPlaced 70 要素のレイアウト位置が確定したとき・変更されたときに実行されるコールバックを提供します。 Box( modifier = Modifier .size(100.dp) .background(Color.Blue) .onPlaced { coordinates: LayoutCoordinates -> println("Composable placed at: ${coordinates.positionInRoot()}") } ) Other

Slide 71

Slide 71 text

© ZOZO, Inc. 6. placeholder 71 ● Wear OS by Googleで、コンテンツの読み込み中などのときにプレースホルダーを表示します。 Chip( onClick = {}, label = { Text( text = labelText, modifier = Modifier .fillMaxWidth() .placeholder(chipPlaceholderState) ) }, icon = { Box( modifier = Modifier .size(ChipDefaults.IconSize) .placeholder(chipPlaceholderState) ) { Icon( painter = painterResource(id = R.drawable.heart), contentDescription = "heart", )}}, ... Other

Slide 72

Slide 72 text

© ZOZO, Inc. 7. placeholderShimmer 72 ● Wear OS by Googleで、コンテンツの読み込み中などのときに光る描画を追加します。 ... colors = PlaceholderDefaults.placeholderChipColors( originalChipColors = ChipDefaults.primaryChipColors(), placeholderState = chipPlaceholderState ), modifier = Modifier .fillMaxWidth() .placeholderShimmer(chipPlaceholderState) ) LaunchedEffect(Unit) { delay(2000) iconResource = R.drawable.tile_preview labelText = "Text" } if (!chipPlaceholderState.isShowContent) { LaunchedEffect(chipPlaceholderState) { chipPlaceholderState.startPlaceholderAnimation() } } Other

Slide 73

Slide 73 text

© ZOZO, Inc. 73 目次 ● 導入・概要 ● プロダクトコードおけるModifierの使用頻度集計 ● Modifier解説 - 全47種 ● 使用回数 総合ランキング

Slide 74

Slide 74 text

使用回数 総合ランキング

Slide 75

Slide 75 text

© ZOZO, Inc. 75 ランキング 1位〜30位 順位 Modifier 使用回数 順位 Modifier 使用回数 順位 Modifier 使用回数 1 padding 1949 11 wrapContentHeight 163 21 verticalScroll 33 2 height 1758 12 clickable 147 22 defaultMinSize 29 3 fillMaxWidth 1305 13 border 136 23 nestedScroll 27 4 background 903 14 fillMaxHeight 104 23 heightIn 27 5 size 879 15 aspectRatio 94 25 pointerInput 22 6 width 768 16 wrapContentWidth 70 25 matchParentSize 22 7 align 588 17 offset 64 27 testTag 19 8 fillMaxSize 521 18 wrapContentSize 63 27 shadow 19 9 weight 406 19 alpha 63 29 rotate 18 10 clip 383 20 zIndex 42 30 animateContentSize 17

Slide 76

Slide 76 text

© ZOZO, Inc. 76 ランキング 31位〜54位 順位 Modifier 使用回数 順位 Modifier 使用回数 順位 Modifier 使用回数 31 focusRequester 15 41 layout 3 47 requiredSize 2 32 horizontalScroll 14 41 onFocusEvent 3 47 widthIn 2 33 scale 12 41 draggable 3 47 imePadding 2 34 alignByBaseline 11 41 windowInsetsTopHeight 3 54 focusable 1 35 clipToBounds 9 41 navigationBarsPadding 3 54 graphicsLayer 1 36 pullRefresh 7 41 statusBarsPadding 3 54 onGloballyPositioned 1 37 scrollable 6 47 onSizeChanged 2 54 paddingFromBaseline 1 37 absolutePadding 6 47 animateEnterExit 2 54 combinedClickable 1 39 alignBy 5 47 layoutId 2 54 requiredWidth 1 40 tabIndicatorOffset 4 47 selectable 2 54 fillParentMaxWidth 1 54 basicMarquee 1 ※62位以降は0回で同率

Slide 77

Slide 77 text

© ZOZO, Inc. 77 まとめ ● 合計49個のModifierを紹介しました。 ● 引数の違いでもさまざまな変化をつけられます。 ● 注意点 ○ Modifier一覧ページではdeprecatedと書いてないものの、実装してみるとdeprecatedの Modifierがありました。(animateItemPlacement、inspectable、menuAnchor) ○ 詳細がリンク切れしているModifierもありました。(tooltipTrigger) Modifierを駆使して良いJetpack Composeライフを!

Slide 78

Slide 78 text

No content