Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Composeの座標を取得する ~コーチマークにおける活用事例~_DroidKaigi.collect#1

kako351
March 31, 2023

Composeの座標を取得する ~コーチマークにおける活用事例~_DroidKaigi.collect#1

kako351

March 31, 2023
Tweet

More Decks by kako351

Other Decks in Technology

Transcript

  1. DroidKaigi.collect{ #[email protected] } 2023/03/31
    [email protected]おいしい健康
    Composeの
    座標を取得する
    ~コーチマークにおける活用事例~

    View Slide

  2. 自己紹介
    kako351 / @kako_351
    おいしい健康 Androidエンジニア
    Androidエンジニア募集中!
    仕事
    ● バイク(ハンターカブ)
    ● ギター
    ● コーヒー自宅焙煎
    趣味
    2

    View Slide

  3. 本日話す内容
    ・事例紹介
    ・ライブラリの紹介 - Spotlight / intro-showcase-viewSpotlightを採用!
    ・Composeの座標を取得する
    ・座標をSpotlightに渡す
    ・まとめ
    3

    View Slide

  4. 事例紹介
    4
    Compose座標を取得して
    何ができるのか活用事例を紹介

    View Slide

  5. 実現したいこと
    コーチマークによるチュートリアル表示。
    初めてアプリを使うユーザーに対して機能の役割
    を説明します。
    ローディング中はコーチマークを表示せず、コン
    テンツを取得できたタイミングで表示します。
    5
    コーチマーク形式の
    チュートリアル

    View Slide

  6. ライブラリで簡単に実装できそう!
    そう思っていたころが僕にもありました……
    6

    View Slide

  7. コーチマークの対象画面は以下のようになっています
    ターゲット領域: Compose
    それ以外の領域: Fragment
    ターゲット領域にスポットライトを当てて、それ以外
    の領域はマスクをかけたい・・・
    7
    対象画面の構成
    Fragment
    Compose

    View Slide

  8. 8
    Spotlight(https://github.com/TakuSemba/Spotlight)
    Kotlinのコーチマークライブラリ。指定したAndroidViewまたは座標を指定してス
    ポットライトを当てることができる。
    Intro-showcase-view(https://github.com/canopas/Intro-showcase-view)
    JetpackComposeで利用可能なコーチマークライブラリ。Modifierに
    introShowCaseTargetをつけることでスポットライトを当てることができる。
    Composeのみで構成されている画面ならこちらが有効そう。

    ライブラリ紹介

    View Slide

  9. 9
    Spotlight(https://github.com/TakuSemba/Spotlight)
    Kotlinのコーチマークライブラリ。指定したAndroidViewまたは座標を指定して
    スポットライトを当てることができる。今回の主役。
    Intro-showcase-view(https://github.com/canopas/Intro-showcase-view)
    JetpackComposeで利用可能なコーチマークライブラリ。Modifierに
    introShowCaseTargetをつけることでスポットライトを当てることができる。
    Composeのみで構成されている画面ならこちらが有効そう。

    ライブラリ紹介
    Composableの座標を渡せばできそう
    Spotlightを採用!

    View Slide

  10. Composeの
    座標を取得する
    10

    View Slide

  11. 11
    RecommendedMenuCard.kt
    @Composable
    fun RecommendedMenuCard(
    //…
    ) {
    Card(
    modifier = Modifier,
    // …
    }

    View Slide

  12. 12
    RecommendedMenuCard.kt
    @Composable
    fun RecommendedMenuCard(
    //…
    ) {
    Card(
    modifier = Modifier.onGloballyPositioned { layoutCoordinates ->
    // layoutCoordinatesにレイアウトの情報が含まれている
    },
    // …
    }
    onGloballyPositionedによって
    コンポジションされた後のレ
    イアウト情報を取得

    View Slide

  13. 13
    Modifier.onGloballyPositioned
    呼び出しタイミング
    コンテンツのグローバル位置が変更された可能性があると呼び出され、呼び出さ
    れるタイミングは座標が確定するコンポジションの後になります。
    呼び出し頻度
    LayoutCoordinatesが使用可能な時に最低1回呼び出さ、ウィンドウ内で要素の位
    置が変わるたびに呼び出されます。
    呼び出されない場合
    変更された要素の画面に対する相対位置が変わっても呼び出されるとは限りませ
    ん。(どういうことだってばよ・・・)
    https://developer.android.com/reference/kotlin/androidx/compose/ui/layout/OnGloballyPositionedModifier

    View Slide

  14. 14
    LayoutCoordinates
    レイアウトの境界を測定するときに用いるホルダー
    拡張関数
    ● boundsInParent()
    親のコンテンツ領域内の子の境界ボックスを返す
    ● boundsInRoot()
    ルート コンポーザブル内のこのレイアウトの境界を返す
    ● boundsInWindow()
    ウィンドウの原点に対するこのレイアウトの境界を返す

    View Slide

  15. 15
    LayoutCoordinates
    レイアウトの境界を測定するときに用いるホルダー
    拡張関数
    ● boundsInParent()
    親のコンテンツ領域内の子の境界ボックスを返す
    ● boundsInRoot()
    ルート コンポーザブル内のこのレイアウトの境界を返す
    ● boundsInWindow()
    ウィンドウの原点に対するこのレイアウトの境界を返す
    ウィンドウ上での位置情報・コン
    テンツサイズが欲しかったのでこ
    れを採用

    View Slide

  16. 16
    RecommendedMenuCard.kt
    Modifier.onGloballyPositioned { layoutCoordinates ->
    val rect = layoutCoordinates.boundsInWindow()
    // Rect.fromLTRB(left = 84.0, top = 701.0, right = 996.0, bottom = 827.0)
    rect.center
    // Offset(x = 540.0, y = 764.0)
    rect.size
    // Size(width = 912.0, height = 126.0)

    View Slide

  17. 17
    RecommendedMenuCard.kt
    Modifier.onGloballyPositioned { layoutCoordinates ->
    val rect = layoutCoordinates.boundsInWindow()
    // Rect.fromLTRB(left = 84.0, top = 701.0, right = 996.0, bottom = 827.0)
    rect.center
    // Offset(x = 540.0, y = 764.0)
    rect.size
    // Size(width = 912.0, height = 126.0)
    Rectを返す
    ウィンドウを原点にした位置
    が返ってくる

    View Slide

  18. 18
    RecommendedMenuCard.kt
    Modifier.onGloballyPositioned { layoutCoordinates ->
    val rect = layoutCoordinates.boundsInWindow()
    // Rect.fromLTRB(left = 84.0, top = 701.0, right = 996.0, bottom = 827.0)
    rect.center
    // Offset(x = 540.0, y = 764.0)
    rect.size
    // Size(width = 912.0, height = 126.0)
    中央の座標も取得可能
    サイズも取得できる

    View Slide

  19. 座標をSpotlightに渡す
    19

    View Slide

  20. HomeFragment#startSpotLight()
    20
    // layoutCoordinatesからTargetを作成
    Target.Builder()
    .setAnchor(
    x = layoutCoordinates.center.x.absoluteValue,
    y = layoutCoordinates.center.y.absoluteValue
    )
    .setShape(
    RoundedRectangle(
    height = layoutCoordinates.size.height * 1.05f,
    width = layoutCoordinates.size.width * 1.05f,
    radius = 25f
    )
    ).build()
    // Spotlightを作成してTargetを渡す
    val spotlight = Spotlight.Builder(requireActivity()).setTargets(targets).build()
    取得した座標を指定

    View Slide

  21. HomeFragment#startSpotLight()
    21
    // layoutCoordinatesからTargetを作成
    Target.Builder()
    .setAnchor(
    x = layoutCoordinates.center.x.absoluteValue,
    y = layoutCoordinates.center.y.absoluteValue
    )
    .setShape(
    RoundedRectangle(
    height = layoutCoordinates.size.height * 1.05f,
    width = layoutCoordinates.size.width * 1.05f,
    radius = 25f
    )
    ).build()
    // Spotlightを作成してTargetを渡す
    val spotlight = Spotlight.Builder(requireActivity()).setTargets(targets).build()
    スポットライトの
    サイズを指定

    View Slide

  22. コーチマークを表示できました。
    Composeの座標やサイズの取得は、
    onGloballyPositionedで割と簡単にできました!
    22
    成果物

    View Slide

  23. まとめ
    23

    View Slide

  24. ● Modifier.onGloballyPositionedでComposeの座標を取得可能
    ● 座標以外にもサイズも取得できる
    ● 座標はRectで取得できるのでCompose外に渡すことも可能
    24
    まとめ
    「もっといい方法があるよ!」という場合は優しく教えてくれると嬉しいです!

    View Slide

  25. ご静聴
    ありがとう
    ございました
    25
    DroidKaigi.collect{ #[email protected] } 2023/03/31

    [email protected]おいしい健康


    View Slide