犬マユの新刊が出ました

犬マユゲでいこうの新刊が発売されました

ワクワクいぬりえ

今回は塗り絵です。

お知らせでした。

カテゴリー: のーと | コメントする

AndroidDevChallenge Week2の景品が届いたよ

ポスターと色鉛筆

もろたー

また届いた

意外とでかい。

開ける

詰まってる。

じゃーん

大きめ!ちなみに色鉛筆は

普通にFABER CASTTELのやつだった。Googleのロゴとかついてないかなーと思ったけど市販品だーね。

ありがとうございました~^^

カテゴリー: のーと | タグ: , | コメントする

『国宝 鳥獣戯画のすべて』に行ってきた

国宝 鳥獣戯画のすべて

ちょっと前に行ってきた。なんか緊急事態宣言がでたから休館になったらしい。あぶねー。

https://chojugiga2020.exhibit.jp/

行くまでは写真撮ってたんだけど、中入ってからは一枚も撮ってないや。

動く歩道で見る甲巻は新鮮でした。いいもん見れたなぁ。

お土産

売り場の蜜っぷりがヤバかったので、なんか考えた方がいいと思います。

ガチャガチャ

かぶったー。

グッズ。

図録買っちゃった。

人を殺せそうな厚み。

満足^^

カテゴリー: のーと | タグ: , | コメントする

AndroidDevChallenge Week1の景品が届いたよ

LEGOトロフィー

なんか届いた

開けてみる

おっ?

届いた~

もっと開けてみる

詰まってる!

じゃーん

すごーい、こういうのもらうの初めてかも。

説明書

とシール。難易度高くね?

作った

けっこー時間かかった!後ろの炎がきっちり入んなかったので逆につけたった。あと部品余ったから目をつけたよ。ありがとーGoogle!

カテゴリー: のーと | タグ: , | コメントする

匿名ラジオCD 炎の章が届いたよ

匿名ラジオCD 炎の章

わーい、今から聞く。3時間ぐらいで売り切れたらしい。すごいね~。再販あるらしいから買えなかった人はそれ待つよろし。

トラックリスト

  1. オープニング
  2. 自分たちがMNKNするエピソードを考えてみよう!
  3. 無いCM①
  4. 相手の裏の顔をリークしろ!ウソ音声流出バトル!
  5. 無いCM②
  6. 無いCM③
  7. スタジオで『ASMR』に挑戦してみよう!
  8. 無いCM④
  9. 一番最初のラジオを4年越しに録り直そう!「キックボード」
  10. エンディング

かんそうはまたあとで

リンク

https://www.youtube.com/channel/UClSsb_e0HDQ-w7XuwNPgGqQ

https://omocoro.shop-pro.jp/?pid=158347122

カテゴリー: のーと | タグ: | コメントする

ViewModelとかLiveDataとかStateとか全然わからない

ViewModelとかLiveData

よくわからない。ミームとかじゃなくてほんとによくわからない。特に益になるような事は書いてない。

サンプル

build.gradleに

implementation "androidx.compose.runtime:runtime-livedata:$compose_version"

を追記。

https://developer.android.com/jetpack/compose/state#viewmodel-state

のを参考に、MainActivity.ktを

@Composable
fun HelloScreen(jcViewModel: JetComViewModel = JetComViewModel()) {
    val name: String by jcViewModel.name.observeAsState("")
    HelloContent(name = name, onNameChange = { jcViewModel.onNameChange(it) })
}

@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello, $name",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.h5
        )
        OutlinedTextField(
            value = name,
            onValueChange = onNameChange,
            label = { Text("Name") }
        )
    }
}

そんでJetComViewModel.ktを

class JetComViewModel : ViewModel() {

    private val _name = MutableLiveData("")
    val name: LiveData<String> = _name

    fun onNameChange(newName: String) {
        _name.value = newName
    }
    
}

クラス名しか変えてない。

ちゃんと動く。

ViewModel内で

private val _name = MutableLiveData("")

MutableLiveDataの変数を内部で用意。

val name: LiveData<String> = _name

LiveDataで外部に公開。

Mainで

val name: String by jcViewModel.name.observeAsState("")

で監視する。

OutlinedTextFieldで文字を入力すると

OutlinedTextField(
    value = name,
    onValueChange = onNameChange,
    label = { Text("Name") }
)

onValueChangeが呼ばれる。ここではonNameChangeが実行される。onNameChangeは

fun HelloContent(name: String, onNameChange: (String) -> Unit) {

この関数の引数で

HelloContent(name = name, onNameChange = { jcViewModel.onNameChange(it) })

呼び出し時にviewmodelのonNameChangeが実行される。viewmodelのonNameChangeは

fun onNameChange(newName: String) {
    _name.value = newName
}

渡された値で

private val _name = MutableLiveData("")

と定義された_nameへ代入して更新する。_nameは

val name: LiveData<String> = _name

なのでつまりnameが変更を検知?するのかな?で、nameが更新したので

HelloContent(name = name, onNameChange = { jcViewModel.onNameChange(it) })

nameを受け取って

Text(
    text = "Hello, $name",
    modifier = Modifier.padding(bottom = 8.dp),
    style = MaterialTheme.typography.h5
)

表示する。こんな感じなんかなー。

MutableLiveDataに配列を使いたい

で、これを配列で使いたいの。でもね、公式に思いっきし

https://developer.android.com/jetpack/compose/state#use-other-types-of-state-in-jetpack-compose

注意: Compose の ArrayList<T> や mutableListOf() のような可変オブジェクトを状態として使用すると、アプリで誤ったデータや古いデータがユーザーに表示される現象が発生します。

ArrayList<T> や可変データクラスなどの非オブザーバブルな可変オブジェクトは、Compose による観測が不可能であり、変更されると再コンポジションがトリガーされます。

非オブザーバブルな可変オブジェクトを使用する代わりに、State<List<T>> や不変の listOf() などのオブザーバブルなデータホルダーを使用することをおすすめします。

やめとけ、と書かれている。でもしたい。。。

変えてみてはエラーメッセージを読み、を繰り返そう。

private val _name = MutableLiveData(mutableListOf("","",""))

て、要素数3のにしたら

val name: LiveData<String> = _name

Type mismatch: inferred type is MutableLiveData<MutableList<String>!> but LiveData<String> was expected

だけど

val name: LiveData<MutableList<String>> = _name

こうしてみる。すると

fun onNameChange(newName: String) {
    _name.value = newName
}

Type mismatch: inferred type is String but MutableList<String>? was expected

まこれはそうよね。これはちょっと置いといて。

Mainの方で

val name: String by jcViewModel.name.observeAsState("")

Property delegate must have a ‘getValue(Nothing?, KProperty&lt;*&gt;)’ method. None of the following functions is suitable:<br/>public inline operator fun &lt;T&gt; State&lt;String&gt;.getValue(thisObj: Any?, property: KProperty&lt;*&gt;): String defined in androidx.compose.runtime

いろいろ試して

val name: MutableList<String> by jcViewModel.name.observeAsState(mutableListOf("","",""))

こうだとエラーでない。

HelloContent(name = name, onNameChange = { jcViewModel.onNameChange(it) })

Type mismatch: inferred type is MutableList<String> but String was expected

なので

fun HelloContent(name :MutableList<String>, onNameChange: (String) -> Unit) {

こう変えてみる。そしたら

OutlinedTextField(
    value = name,
    onValueChange = onNameChange,
    label = { Text("Name") }
)

これが

None of the following functions can be called with the arguments supplied:<br/>public fun OutlinedTextField(value: TextFieldValue, onValueChange: (TextFieldValue) -&gt; Unit, modifier: Modifier = …, enabled: Boolean = …, readOnly: Boolean = …, textStyle: TextStyle = …, label: (() -&gt; Unit)? = …, placeholder: (() -&gt; Unit)? = …, leadingIcon: (() -&gt; Unit)? = …, trailingIcon: (() -&gt; Unit)? = …, isError: Boolean = …, visualTransformation: VisualTransformation = …, keyboardOptions: KeyboardOptions = …, keyboardActions: KeyboardActions = …, singleLine: Boolean = …, maxLines: Int = …, interactionSource: MutableInteractionSource = …, colors: TextFieldColors = …): Unit defined in androidx.compose.material<br/>public fun OutlinedTextField(value: String, onValueChange: (String) -&gt; Unit, modifier: Modifier = …, enabled: Boolean = …, readOnly: Boolean = …, textStyle: TextStyle = …, label: (() -&gt; Unit)? = …, placeholder: (() -&gt; Unit)? = …, leadingIcon: (() -&gt; Unit)? = …, trailingIcon: (() -&gt; Unit)? = …, isError: Boolean = …, visualTransformation: VisualTransformation = …, keyboardOptions: KeyboardOptions = …, keyboardActions: KeyboardActions = …, singleLine: Boolean = …, maxLines: Int = …, interactionSource: MutableInteractionSource = …, colors: TextFieldColors = …): Unit defined in androidx.compose.material

@Composable invocations can only happen from the context of a @Composable function

そしたら

value = name[0],

こう変えた。Mainの方はエラー表示されなくなった。

じゃあ上でほっといたviewmodelの

fun onNameChange(newName: String) {
    _name.value = newName
}

_name.value[0] = newName

こうしたら

Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type MutableList<String>?

なので

_name.value!![0] = newName

こうしてみた。一応これでエラーは表示されなくなったけど…

動かしてみると

うまく動かない。つまりは

注意: Compose の ArrayList<T> や mutableListOf() のような可変オブジェクトを状態として使用すると、アプリで誤ったデータや古いデータがユーザーに表示される現象が発生します。

ArrayList<T> や可変データクラスなどの非オブザーバブルな可変オブジェクトは、Compose による観測が不可能であり、変更されると再コンポジションがトリガーされます。

非オブザーバブルな可変オブジェクトを使用する代わりに、State<List<T>> や不変の listOf() などのオブザーバブルなデータホルダーを使用することをおすすめします。

これだ。がっくし。

参考

https://developer.android.com/jetpack/compose/state

https://developer.android.com/reference/android/arch/lifecycle/LiveData

https://developer.android.com/topic/libraries/architecture/livedata#observe_livedata_objects

https://developer.android.google.cn/jetpack/compose/libraries#streams

https://developer.android.google.cn/reference/kotlin/androidx/compose/runtime/livedata/package-summary

https://stackoverflow.com/questions/47941537/notify-observer-when-item-is-added-to-list-of-livedata

https://teratail.com/questions/181174

カテゴリー: のーと | タグ: , , , , | コメントする

Type ‘TypeVariable(T)’ has no method ‘getValue(Nothing?, KProperty<*>)’ and thus it cannot serve as a delegateってエラー

Type ‘TypeVariable(T)’ has no method ‘getValue(Nothing?, KProperty<*>)’ and thus it cannot serve as a delegate

現象

var name by rememberSaveable { mutableStateOf("") }

って構文を使おうとした時にタイトルのエラーでた。

対応

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

を追加。

参考

https://www.reddit.com/r/android_devs/comments/jff2vp/jetpack_compose_am_i_stupid_or_is_the_by_remember/

カテゴリー: のーと | タグ: , , , | 1件のコメント

Invalid Gradle JDK configuration found.ってエラー

Invalid Gradle JDK configuration found

AndroidDevChallengeに参加してた時は気づかなかったのだけど、タイトルのエラーが出てNew Projectが作れなかった。解決はしていないけど 解決したので調べたことやったこと。

現象

AndroidStudioのCanaryビルドを使用してNewProjectを作ろうとすると、どのActivityを選んでもInvalid Gradle JDK configuration found.というエラーが出てProjectがビルドされない。

また、IDE Fatal Errorsとして

https://gist.github.com/dalomo-net/b712de9d5adf0ed13749b755a1371fe0

ていうエラーが出た。

AndroidDevChallengeのテンプレートリポジトリをCloneしても問題は特に起こらなかったのになんでなんだろう。

環境

Build: AI-203.7148.57.2031.7226969, 202103221950,

AI-203.7148.57.2031.7226969, JRE 11.0.8+10-b944.6842174×64 JetBrains s.r.o, OS Windows 10(amd64) v10.0 , screens 1360.0×768.0

AS: Arctic Fox | 2020.3.1 Canary 12; Kotlin plugin: 203-1.4.30-release-AS7148.5; Android Gradle Plugin: (plugin information not found); Gradle: 6.8.3; NDK: from local.properties: (not specified), latest from SDK: (not found); LLDB: pinned revision 3.1 not found, latest from SDK: (package not found); CMake: from local.properties: (not specified), latest from SDK: (not found), from PATH: (not found)Source: user_sentiment_feedback

Open Gradle SettingsとChange JDK location

Open Gradle Settingsの方は何を変えればいいのか分からなかった。ので、Change JDK locationを変えてみる。

AS同梱のJREじゃなく、ローカルにインストールしてJAVA_HOMEにパスを通してるJDKを使ってみる。するとCould not initialize class org.codehaus.groovy.reflection.ReflectionCacheというエラーになった。

https://kokufu.blogspot.com/2015/07/android-studio-invalid-gradle-jdk.html

Could not initialize class org.codehaus.groovy.reflection.ReflectionCache

GradleのバージョンとJDEのバージョンが合ってないかららしい。

変えてみる。するとビルドは通った。

ところがProjectが正しく構築されてない。中途半端な形になっている。

“Android”の項目がなかったり、MainActivityが作成されてなかったり、新規ファイルの項目が少なかったり。JDKをEmbedのものにしても結果は同じ。

https://taktak.jp/2020/04/02/4275/

https://qiita.com/mojave/items/080a1aed816912166faa

.ideaを削除

IssueTrackerで検索してみるといくつかトピックがあった。そのうちの一つであるProject内の.ideaを削除して再ビルドをやってみたがダメだった。

https://issuetracker.google.com/#

https://issuetracker.google.com/u/1/issues?q=Invalid%20Gradle%20JDK%20configuration

AndroidStudioの再インストール

CanaryもStableも一回削除して再インストールしてみたけど、それでもダメだった。

Windowsに新規ユーザー作ってそっちで開く

まっさら環境でやったらどうなんのかな?と思ってやってみることにした。

そしたらなんかできちゃったんですけど!この画面初めて見たわ。あまりにあっさりできてしまったので、何が原因なのかよくわからない。うーん今度からJetpackComposeを使用したアプリを作る場合はいちいちユーザー切り替えなきゃいけんのだろうか。さすがに安定版リリースの際にはここらへんの不具合直してからリリースしてくれると思うんだけどなぁ~。

キャッシュの削除

と思ったら直った!

C:\Users\<ユーザーネーム>\.gradle

とついでに

C:\Users\<ユーザーネーム>\.android

をぶち消したら設定が初期化されてちゃんと構築されるようになった。どっちを消したら良かったのかはわかりません。ただ最悪既存プロジェクトがビルドできなくなるかもなので注意したほうがいいと思う。

カテゴリー: のーと | タグ: , | コメントする

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

Speed round

https://android-developers.googleblog.com/2021/03/android-dev-challenge-3.html

https://github.com/android/android-dev-challenge-compose/blob/assets/Bloom.zip

Week3

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

https://github.com/dalomo-net/week3-Speed-Round

悲しい。

何ができなかったか

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

全体

  • ダークテーマでの色や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関係なくね、と思いつつ。

https://stackoverflow.com/questions/38382283/change-status-bar-text-color-when-primarydark-is-white

ついでに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()

てする。

https://github.com/google/accompanist

https://google.github.io/accompanist/insets/

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

これ

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にしてあげると勝手にモードに合わせて表示してくれたりするらしい。

https://developer.android.com/jetpack/compose/themes?hl=ja#color

https://developer.android.com/guide/topics/resources/providing-resources?hl=ja#Compatibility

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

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

Welcome

葉っぱが切れる

alignment = Alignment.CenterStart

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

https://alexzh.com/jetpack-compose-layouts/

TextをBaseline基準の間隔にする

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

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

https://developer.android.com/jetpack/compose/layout#layout-modifier

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)

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

https://stackoverflow.com/questions/64376333/background-color-on-button-in-jetpack-compose

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
    )
}

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

https://medium.com/google-developer-experts/exploring-jetpack-compose-button-4cfb8355e50

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)
                )
            }
        }
    }
}

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

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

https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#card

あとなぜかこのあたりから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がなんか悪いのかなーといろいろ調べてたら

https://developer.android.com/jetpack/compose/libraries#image-loading

https://github.com/google/accompanist/blob/main/coil/README.md

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ってのを使えばいいんだろうか。試しに

https://developer.android.com/guide/topics/graphics/drawables?hl=ja#drawables-from-images

https://stackoverflow.com/questions/58743541/how-to-get-context-in-jetpack-compose

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

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

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

https://stackoverflow.com/questions/4896223/how-to-get-an-uri-of-an-image-resource-in-android

を参考に

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使うとこれも改善された。なぜかはよく分かりません。

https://stackoverflow.com/questions/63794544/lazycolumnfor-is-not-smooth-scrolling

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*/ }
        )
    }
}

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

https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#bottomappbar

https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#bottomnavigation

完成

https://github.com/dalomo-net/week3-Speed-Round

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

カテゴリー: のーと | タグ: , , , , | コメントする

Jetpack ComposeのAndroid Dev Challengeに応募した② Week2

CountdownTimer

https://android-developers.googleblog.com/2021/03/android-dev-challenge-2.html

Week2

Week2はカウントダウンタイマーだった。みんななんでそんな簡単にカウントダウンタイマー自体を作れるんだろう、すごいなぁ。

できたやつ

めんどいのでできたのだけ。

https://github.com/dalomo-net/countdown-timer

https://twitter.com/dalomo_dalomo/status/1368124410490589185

ほんとはちゃんとできてないんだ…。状態は加味したけどアニメーションは使ってない。タイマーもちゃんとは動かない。です。

参考

https://www.raywenderlich.com/books/jetpack-compose-by-tutorials/v1.0/chapters/3-building-layout-groups-in-compose

https://qiita.com/nimani76/items/040dd28717eabe3ea781#%E6%95%B0%E5%80%A4%E3%81%8B%E3%82%89%E6%96%87%E5%AD%97%E5%88%97

https://techbooster.org/android/7810/

https://developer.android.com/reference/android/os/CountDownTimer

https://www.youtube.com/watch?v=A270gvPJh_A

https://medium.com/mobile-app-development-publication/simple-android-animation-with-jetpack-compose-6eb718928f9b

カテゴリー: のーと | タグ: , , , , | コメントする