Jetpack ComposeのAndroid Dev Challengeに応募できなかった Week3

スポンサーリンク
スポンサーリンク

Speed round

Android Dev Challenge: Week 3 - Speed round
News and insights on the Android platform, developer tools, and events.
Build software better, together
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 330 million projects.
スポンサーリンク

Week3

お題が出るので、お題に沿ってデザインをコードに実装していく。でもできませんでしたー。

GitHub - dalomo-net/week3-Speed-Round
Contribute to dalomo-net/week3-Speed-Round development by creating an account on GitHub.

悲しい。

スポンサーリンク

何ができなかったか

大変悔しいので、何ができなかったのかをまとめて、一つずつ潰していってみることにした。

全体

  • ダークテーマでの色やresの切り替え
  • ステータスバー・ナビゲーションバー消してない

Welcome

  • 葉っぱの画像が切れてる
  • Textの間隔がbaselineを意識したものになってない
  • ボタンのサイズ・シェイプが変
  • ボタンの背景色を変えてない

Log in

  • ボタンのサイズ・シェイプが変
  • ボタンの背景色を変えてない

ついで

  • 入力欄にフォーカスした時、説明文字が消えない
  • パスワード欄の文字入力が丸見え

Home

  • Search欄にアイコンがない
  • テキストの間隔が変
  • 下のアプリバー
    • アイコンの大きさ
    • アイコンのキャプション
    • 選択・非選択時の色の切り替え
    • 間隔の整列

BrowseThemes

  • カードが作れてない
  • elevationを設定できていない
  • スクロールできるリストの形になってない

Design your home garden

  • テキストの間隔が変
  • dividerの位置が変
  • スクロールできるリストの形になってない

こんなところでしょうか…。

スポンサーリンク

改善していってみる

完成しますように。とりあえず見れるようにしたい。これが正しいというわけではない。

全体

ステータスバーを透過する

themes.xmlに

<item name="android:statusBarColor" tools:targetApi="l">@android:color/transparent</item>
<item name="android:windowLightStatusBar">true</item>

初っ端からJetpackCompose関係なくね、と思いつつ。

Change status bar text color when primaryDark is white
I am trying to reproduce the behaviour of Google Calendar application: but I have not found a way to change the status text color. If i set the colorPrimaryDar...

ついでにHomeでバーがバーに収まるように

ナビゲーションバー内に収まるようにする

projectのbuild.gradleに

ext.accompanist_version = '0.6.2'

appのbuild.gradleに

implementation "dev.chrisbanes.accompanist:accompanist-coil:$accompanist_version"
implementation "dev.chrisbanes.accompanist:accompanist-insets:$accompanist_version"

onCreateで

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    WindowCompat.setDecorFitsSystemWindows(window, false)
    setContent {
        MyTheme {
            ProvideWindowInsets {
                MyApp()
            }
        }
    }
}

こんな。そんでコンテンツ全体に効くところに

modifier = Modifier.navigationBarsPadding()

てする。

GitHub - google/accompanist: A collection of extension libraries for Jetpack Compose
A collection of extension libraries for Jetpack Compose - GitHub - google/accompanist: A collection of extension libraries for Jetpack Compose
Guide - Accompanist
A group of libraries to help write Jetpack Compose apps.

ライト・ダークでのリソース切り替え

これ

MaterialTheme.colors.isLight

でなんか判定ができるみたいなので、ifで分岐させたり

if (MaterialTheme.colors.isLight) R.drawable.light_logo else R.drawable.dark_logo

ResourseManagerでImport Drawablesの時にdark側のQQUALIFIER TYPE-VALUEをNightMode-NightTimeにしてあげると勝手にモードに合わせて表示してくれたりするらしい。

Compose のデザイン システム  |  Jetpack Compose  |  Android Developers
アプリのリソースの概要  |  Android デベロッパー  |  Android Developers

ページごとにファイルを分割した

新しくファイル作ってコードをそっちに移しただけ。

Welcome

葉っぱが切れる

alignment = Alignment.CenterStart

を追加した。なぜこうすると上手くいくのかは謎。

Jetpack Compose: Layouts
Introduction Jetpack Compose provides a declarative way of building the UI of the Android app. Layouts are an essential component for creating UI, and Jetpack C...

TextをBaseline基準の間隔にする

modifier = Modifier.paddingFromBaseline(top = 32.dp, bottom = 40.dp)

とした。公式の日本語訳のページだとpaddingFromBaselineが載ってなくて迷った。原文にあたれってのはこういうことかと呪ったよね。

Layouts in Compose  |  Android Developers

Buttonのサイズを変える

Button(
    onClick = { },
    shape = MaterialTheme.shapes.medium,
    modifier = Modifier
        .fillMaxWidth()
        .height(48.dp)
        .padding(start = 16.dp,end = 16.dp)
)

潰れてたのが直った。

Buttonの背景色を変える

colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colors.secondary)

これなんでこんな書き方なんだろう。探すの手間どった。

background color on Button in Jetpack Compose
Button(backgroundColor = Color.Yellow) { Row { Image(asset = image) Spacer(4.dp) Text("Button") } } I can not figure ...

TextButtonを使う

TextButton(
    onClick = { navController.navigate("login") },
    modifier = Modifier
        .fillMaxWidth()
        .height(48.dp)
        .padding(top = 8.dp)
) {
    Text(
        text = "Log in",
        color = MaterialTheme.colors.secondary,
        style = MaterialTheme.typography.button
    )
}

こういうのがあるのね…。どうすれば透明になるんだ~?とかやってたわ。

Exploring Jetpack Compose: Button
This was originally posted on my personal blog

Log in

TextをBaseline基準の間隔にする

modifier = Modifier.paddingFromBaseline(top = 184.dp, bottom = 16.dp),

先程に続き再び。これTextの下はOutlinedTextFieldの方で変えたほうがいいのかな。どっちなんだろ。

TextFieldにプレースホルダーを設定する

placeholder = {
    Text(text = "Email address", style = MaterialTheme.typography.body1)
}

こうだった。これで文字入力し始めると文字が消える。

TextFieldの入力表示を隠す

visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
    keyboardType = KeyboardType.Password
)

上だけで隠れる。下は知らん。

https://android–code.blogspot.com/2021/03/jetpack-compose-password-textfield.html

Buttonの形と背景色を変える

Button(
    onClick = { navController.navigate("home") },
    shape = MaterialTheme.shapes.medium,
    modifier = Modifier
        .fillMaxWidth()
        .height(48.dp),
    colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colors.secondary)
) {
    Text(
        text = "Log in",
        color = MaterialTheme.colors.background,
        style = MaterialTheme.typography.button
    )
}

さっきと一緒。

Home

TextField内の最初にアイコンを付ける

leadingIcon = {
    Icon(
        imageVector = Icons.Default.Search,
        contentDescription = "search",
        Modifier.size(18.dp)
    )
}

Iconというのがあるのだな…。頑張ってリソースに追加してたよ。。。

Browse Themesのカード作り

ひぃひぃ言いながら

@Composable
fun ThemeCard(n: String, rid: Int) {

    Card(
        modifier = Modifier
            .size(136.dp)
            .clickable { },
        shape = MaterialTheme.shapes.small,
        elevation = 1.dp,
        backgroundColor = MaterialTheme.colors.surface
    ) {
        Column(modifier = Modifier.fillMaxSize()) {
            Image(
                painter = painterResource(id = rid),
                contentDescription = n,
                contentScale = ContentScale.Crop,
                modifier = Modifier
                    .height(96.dp)
            )
            Box() {
                Text(
                    text = n,
                    style = MaterialTheme.typography.h2,
                    modifier = Modifier
                        .padding(start = 8.dp)
                        .paddingFromBaseline(top = 24.dp)
                )
            }
        }
    }
}

こんな感じで書いたんだけど、結果

うまくいかん。ちょっとどうやってもキレイに表示されんのでこれはもういいや…。

androidx.compose.material  |  Android Developers

あとなぜかこのあたりからCannot access class ‘androidx.compose.ui.graphics.painter.Painter’. Check your module classpath for missing or conflicting dependenciesというエラーが出るようになった。ImageとpainterResourceのところに赤波線が付いてるけどBuildは通る…。解決策が分からないのでほっといてる。

このカード達をLazyRowを使って行方向に並べているわけだけど、他の人と比べるとなんかカクカクしてしまっている。なんでなんだろう、多分何かが違うんだろうけど、その何かが分からないー。

Design your home gardenの並びにフィルターアイコンを付ける

Row(
    horizontalArrangement = Arrangement.SpaceBetween,
    verticalAlignment = Alignment.CenterVertically,
    modifier = Modifier
        .fillMaxWidth()
        .paddingFromBaseline(top = 40.dp)
) {

    Text(
        text = "Design your home garden",
        style = MaterialTheme.typography.h1,
        color = MaterialTheme.colors.onPrimary,
    )
    Icon(
        imageVector = Icons.Default.FilterList,
        contentDescription = "filterlist",
        modifier = Modifier.size(24.dp)
    )
}

こうなった。Rowにpaddingfrombaselineに気づくのに時間かかった。

LazyColumnに2つ以上アイテムがあると落ちる

@Composable
fun LazyColumnList() {
    LazyColumn(verticalArrangement = Arrangement.spacedBy(8.dp))
    {
        item {
            PlantItem(n = "Monstera", rid = R.drawable.monstera)
        }
        item {
            PlantItem(n = "Aglaonema", rid = R.drawable.aglaonema)
        }
        item {
            PlantItem(n = "Peace Lily", rid = R.drawable.peace_lilly)
        }
        item {
            PlantItem(n = "Fiddle Leaf tree", rid = R.drawable.fiddle_leaf)
        }
        item {
            PlantItem(n = "Snake plant", rid = R.drawable.snake_plant)
        }
        item {
            PlantItem(n = "Pothos", rid = R.drawable.pothos)
        }
    }
}

こうして

@Composable
fun PlantItem(n: String, rid: Int) {
    Row(
        modifier = Modifier
            .height(64.dp)
            .fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically
    ) {
        Image(
            painter = painterResource(id = rid),
            contentDescription = n,
            modifier = Modifier.clip(shape = MaterialTheme.shapes.small)
        )
        Column() {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween,
                verticalAlignment = Alignment.CenterVertically
            ) {

                Column(modifier = Modifier.padding(start = 16.dp)) {

                    Text(
                        text = n,
                        style = MaterialTheme.typography.h2,
                        color = MaterialTheme.colors.onPrimary,
                        modifier = Modifier.paddingFromBaseline(top = 24.dp)
                    )
                    Text(
                        text = "This is a description",
                        style = MaterialTheme.typography.body1,
                        color = MaterialTheme.colors.onPrimary
                    )
                }
                Checkbox(
                    checked = true,
                    onCheckedChange = {},
                    modifier = Modifier.size(24.dp)
                )
            }
            Divider(modifier = Modifier.padding(start = 8.dp))
        }
    }
}

こう作ってみたんだけどLazyColumnのItemが2つ以上になるとアプリが落ちる。なんでだーと思ってPlantItemの内容を一個ずつ削って見るとImageを削ったときだけはちゃんと表示される。つーことはImageがなんか悪いのかなーといろいろ調べてたら

Compose and other libraries  |  Android Developers
Build software better, together
GitHub is where people build software. More than 100 million people use GitHub to discover, fork, and contribute to over 330 million projects.

CoilImageっていうのが使えるようになるやつがあるみたい。そんでdataには読み込みたいURLを指定するらしいんだがres/drawableに入れてる場合はどうするんだろう。

dataが対応してる型が

String (mapped to a Uri)
Uri (“android.resource”, “content”, “file”, “http”, and “https” schemes only)
HttpUrl
File
DrawableRes
Drawable
Bitmap

Drawableってのを使えばいいんだろうか。試しに

ドローアブルの概要  |  Android デベロッパー  |  Android Developers
How to get Context in Jetpack Compose
fun createListItem(itemIndex: Int) { Padding(left = 8.dp, right = 8.dp, top = 8.dp, bottom = 8.dp) { FlexRow(crossAxisAlignment = CrossAxisAlignment...

ここらへん参考にしてみて

val context = LocalContext.current
val image : Drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.desert_chic, null)!!

こんなコード書いてみたんですが、表示されませんでした…。じゃあURIとか?と思って

how to get an uri of an image resource in android
I need to open an intent to view an image as follows: Intent intent = new Intent(Intent.ACTION_VIEW); Uri uri = Uri.parse("@drawable/sample_1.jpg"); intent.set...

を参考に

val path: Uri = Uri.parse("android.resource://com.example.androiddevchallenge/" + R.drawable.desert_chic)

こうして、dataにpathを渡したけどこれも表示されませんでした…。他に引数に@DrawableResつけてみたりしたけど駄目だった。

contentDescription = ""

これ!これが足りなかった!

CoilImage(
    data = rid,
    contentDescription = "",
    modifier = Modifier
        .size(64.dp)
        .clip(shape = MaterialTheme.shapes.small),
    contentScale = ContentScale.Crop
) {}

こう!でいけたわ~。

LazyColumn, LazyRowのスクロールがカクカクする

CoilImage使うとこれも改善された。なぜかはよく分かりません。

LazyColumnFor is not smooth scrolling
So, I have implemented a lazycolumnfor to work with a list of recipe elements, the thing is that it does not smooth scroll, if I just scroll fast it stutters ti...

BottomBarにLazyColumnのリストが隠れる

contentPadding = PaddingValues(bottom=56.dp)

LazyColumnにBottomBarの高さのpaddingを入れてみたけどもっとキレイなやり方ないんだろうか。

BottomAppBarとBottomNavigationの違い

さっきからBottomAppBarって言ってたような気がするが、BottomAppBarはページ内でなんらかのアクションをする際に使うやつで、BottomNavigationはページ遷移をするときに使うやつらしい。多分。で、今回の場合はBottomNavigationを使うんかな。

BottomNavigationを実装する

@Composable
fun BottomBar() {

    BottomNavigation(
        backgroundColor = MaterialTheme.colors.primary,
        modifier = Modifier.height(56.dp)
    ) {
        BottomNavigationItem(
            selected = true,
            onClick = { /*TODO*/ },
            icon = { Icon(imageVector = Icons.Default.Home, contentDescription = "Home") },
            label = { Text(text = "Home",style = MaterialTheme.typography.caption) }
        )
        BottomNavigationItem(
            selected = false,
            icon = { Icon(imageVector = Icons.Default.FavoriteBorder, contentDescription = "favorite") },
            label = { Text(text = "Favorites",style = MaterialTheme.typography.caption) },
            onClick = { /*TODO*/ }
        )
        BottomNavigationItem(
            selected = false,
            icon = { Icon(imageVector = Icons.Default.AccountCircle, contentDescription = "profile") },
            label = { Text(text = "Profile",style = MaterialTheme.typography.caption) },
            onClick = { /*TODO*/ }
        )
        BottomNavigationItem(
            selected = false,
            icon = { Icon(imageVector = Icons.Default.ShoppingCart, contentDescription = "cart") },
            label = { Text(text = "Cart",style = MaterialTheme.typography.caption) },
            onClick = { /*TODO*/ }
        )
    }
}

最初なぜかアイコンが上にはみ出してキャプションしかバー内に入ってなかった。けどなんか色々やって↑な感じにしたらいい感じだった。

androidx.compose.material  |  Android Developers
androidx.compose.material  |  Android Developers
スポンサーリンク

完成

GitHub - dalomo-net/week3-Speed-Round
Contribute to dalomo-net/week3-Speed-Round development by creating an account on GitHub.

いいんじゃないでしょうか…とりあえず形にはできたよね?まぁチェックボックスの初期値とかダークモードの確認全くやってない(スマホが対応してなかったしプレビューが効かん)とか詰めればきりないんだけどね。あー疲れた!ちなみに第4週は天気アプリだったけど参加はしなかった…。参加してたら天気ルーレットアプリを作りたかったかな、残念!でもまぁここまで参加できて楽しかった~(^^)あ、あと時間帯違いのWeTradeとMySootheがあるから時間あったらやってみようかなぁ~。

コメント

タイトルとURLをコピーしました