Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Composeで天気を表示する #11

Open
4 tasks
github-actions bot opened this issue Apr 2, 2024 · 0 comments
Open
4 tasks

Composeで天気を表示する #11

github-actions bot opened this issue Apr 2, 2024 · 0 comments
Labels
Compose Jetpack ComposeでUIを作成する課題です 必須 必ず取り組む課題です

Comments

@github-actions
Copy link

github-actions bot commented Apr 2, 2024

🌤️ 天気を取得してメイン画面に表示しましょう

Note

Required(先に完了させましょう)

Next(次に取り組みましょう)

課題内容

Reloadボタンをタップしたら画面を更新する実装を行います

  • APIを利用して天気を取得する
  • 取得した天気を画面の天気アイコンに反映させる
  • 天気画面のComposableを分割する
  • 各Composableをstatelessにする

利用するAPI

apiモジュールのYumemiWeatherを利用します

    fun fetchSimpleWeather() : String

天気を表す文字列 "sunny" or "cloudy" or "rainy" or "snow"を返します
mainブランチの段階ではネットワーク上での通信はせずランダムな値を返します)

天気画像

こちらのSVGを利用してください

sunny
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4.069 13h-4.069v-2h4.069c-.041.328-.069.661-.069 1s.028.672.069 1zm3.034-7.312l-2.881-2.881-1.414 1.414 2.881 2.881c.411-.529.885-1.003 1.414-1.414zm11.209 1.414l2.881-2.881-1.414-1.414-2.881 2.881c.528.411 1.002.886 1.414 1.414zm-6.312-3.102c.339 0 .672.028 1 .069v-4.069h-2v4.069c.328-.041.661-.069 1-.069zm0 16c-.339 0-.672-.028-1-.069v4.069h2v-4.069c-.328.041-.661.069-1 .069zm7.931-9c.041.328.069.661.069 1s-.028.672-.069 1h4.069v-2h-4.069zm-3.033 7.312l2.88 2.88 1.415-1.414-2.88-2.88c-.412.528-.886 1.002-1.415 1.414zm-11.21-1.415l-2.88 2.88 1.414 1.414 2.88-2.88c-.528-.411-1.003-.885-1.414-1.414zm6.312-10.897c-3.314 0-6 2.686-6 6s2.686 6 6 6 6-2.686 6-6-2.686-6-6-6z"/></svg>
cloudy
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 3c-4.006 0-7.267 3.141-7.479 7.092-2.57.463-4.521 2.706-4.521 5.408 0 3.037 2.463 5.5 5.5 5.5h13c3.037 0 5.5-2.463 5.5-5.5 0-2.702-1.951-4.945-4.521-5.408-.212-3.951-3.473-7.092-7.479-7.092z"/></svg>
rainy
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13 2.056v-1.056c0-.552-.448-1-1-1s-1 .448-1 1v1.052c-6.916.522-10.372 5.594-11 9.906 1.864-2.677 6.136-2.677 8 0 1.839-2.641 6.047-2.685 7.917 0 1.864-2.677 6.219-2.677 8.083 0-.625-4.291-4.125-9.333-11-9.902zm0 10.101v8.843c0 1.657-1.343 3-3 3s-3-1.343-3-3v-1h2v1c0 .551.449 1 1 1s1-.449 1-1v-8.866c.68-.226 1.27-.242 2 .023z"/></svg>
snow
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><path d="M420.313,248.953c-9.625-19.672-22.656-37.328-38.344-52.234c8.156-17.656,12.719-37.359,12.719-58.031c0-19.094-3.875-37.391-10.906-53.984c-10.531-24.922-28.094-46.047-50.219-61.016C311.438,8.75,284.656,0,256,0c-19.094,0-37.375,3.875-54,10.906C177.094,21.453,155.969,39,141,61.141c-14.938,22.109-23.688,48.891-23.688,77.547c0,20.672,4.563,40.375,12.719,58.031c-15.688,14.906-28.719,32.563-38.344,52.234c-11.844,24.219-18.5,51.516-18.5,80.234c0,25.188,5.125,49.281,14.375,71.156c13.875,32.844,37.031,60.719,66.219,80.422C182.938,500.469,218.188,512,256,512c25.188,0,49.281-5.125,71.156-14.375c32.844-13.891,60.719-37.047,80.438-66.219c19.688-29.156,31.219-64.422,31.219-102.219C438.813,300.469,432.156,273.172,420.313,248.953zM391,386.203c-11.094,26.266-29.688,48.672-53.094,64.484c-23.406,15.797-51.5,25-81.906,25.016c-20.281-0.016-39.5-4.109-57.031-11.516c-26.281-11.094-48.656-29.703-64.469-53.094c-15.813-23.406-25-51.5-25.031-81.906c0.031-23.125,5.344-44.875,14.844-64.281c9.469-19.391,23.156-36.422,39.813-49.859c7.094-5.703,8.875-15.734,4.156-23.516c-9.313-15.438-14.656-33.438-14.656-52.844c0-14.188,2.844-27.609,8.031-39.844c7.75-18.359,20.75-34.031,37.125-45.063C215.125,42.734,234.719,36.313,256,36.297c14.188,0.016,27.594,2.875,39.844,8.047c18.344,7.75,34.031,20.766,45.063,37.109c11.047,16.359,17.469,35.969,17.469,57.234c0,19.406-5.344,37.406-14.656,52.844c-4.719,7.781-2.938,17.813,4.156,23.516c16.656,13.438,30.328,30.469,39.813,49.859c9.5,19.406,14.813,41.156,14.813,64.281C402.5,349.469,398.406,368.688,391,386.203z" /><path d="M230.781,132.391c0-8.906-7.219-16.141-16.125-16.141s-16.125,7.234-16.125,16.141c0,8.922,7.219,16.141,16.125,16.141S230.781,141.313,230.781,132.391z" /><path d="M297.344,116.25c-8.906,0-16.125,7.234-16.125,16.141c0,8.922,7.219,16.141,16.125,16.141s16.125-7.219,16.125-16.141C313.469,123.484,306.25,116.25,297.344,116.25z" /></svg>

各天気アイコンの色は以下のとおり

  • sunny #FF0000
  • cloudy #888888
  • rainy #0000FF
  • snow #44EEFF

動作イメージ

Composableの粒度

画面の構成を踏まえてComposable関数を分割します。個々のComposable関数を小さくすることで、「何を表示すればいいか」という注目の範囲や責任も小さくなり設計し易くなります。複数画面で同じようなUI要素を表示したい場合などは、Composable関数を再利用することもできます。

💡 例えば図のような分割方法が考えられます

  • WeatherApp : App全体
    • WeatherInfo : 天気情報(アイコン+気温表記)
    • ActionButtons : アクションボタンのグループ

composable-example

状態ホイスティング

ところでWeatherInfoが表示する天気アイコン・気温を直書きしたら再利用できません。状態を引数として外部から受け取り、動的に表示内容を変更できるようにします。またActionButtonsでボタンがクリックされたときの処理に関しても、ActionButtons内側に直書きしては再利用できません。そこでイベントのコールバック関数を外部から引数に渡すようにします。

stateDiagram-v2
  WeatherApp --> ChildComposable: state
  ChildComposable --> WeatherApp: event
Loading

このように状態は呼び出し元の親から子へ、逆にイベントは子から親の呼び出し元へ流れるような設計パターンを状態ホイスティングと呼びます。

利点

  • ✅ 信頼できる唯一の情報源:状態の情報源は呼び出し元1箇所に限定され状態は親から子へ単方向に伝搬するため、状態の管理が容易となりバグも防げます
  • ✅ 状態の分離:Composable内部に一切の状態を持たないStatelessな設計にすると状態管理をUIから分離できます

状態とコンポジション

宣言的UIであるComposeで画面を更新するには新しい引数でComposableを呼び出します(コンポジション)。状態を更新したときコンポジションを自動でトリガーさせるため、MutableStateで状態を保持しましょう。

Tip

  • Composableが呼び出される度にMutableStateが初期化されるのを防ぐためにはrememberを利用します
  • 状態ホスティングにより唯一の情報源はActivityとなるため、状態の管理(MutableStateの定義&APIの呼び出し)はActivity直下のComposableにのみ現れるはずです

参考資料

@github-actions github-actions bot added Compose Jetpack ComposeでUIを作成する課題です 必須 必ず取り組む課題です labels Apr 2, 2024
@github-actions github-actions bot added this to the 2. メイン画面の作成 milestone Apr 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Compose Jetpack ComposeでUIを作成する課題です 必須 必ず取り組む課題です
Projects
None yet
Development

No branches or pull requests

0 participants