- 投稿日:2020-11-04T23:12:35+09:00
【Android】SearchView 使ってみた
【Android】SearchView 使ってみた
SearchViewとは
文字を入力してもらうような検索レイアウトを作るのって、面倒だなと思ってたら、もともと用意されているレイアウトで、SearchViewというものがありました。
- SearchViewの例
使い方
使い方はとても簡単です。
- レイアウト
searchView.xml<androidx.appcompat.widget.SearchView android:id="@+id/search_view" // サイズはお任せで android:layout_width="match_parent" android:layout_height="wrap_content" // ヒントとして、文字入力部分に表示される文字列 app:queryHint="キーワード検索" // 虫眼鏡の画像の表示・非表示を設定 android:iconifiedByDefault="true"/>現状で使いそうだと思ったリスナー
OnQueryTextListener
SearchViewに、文字が入力、または入力後に完了(検索)が行われた時のリスナークラス
- 使い方の例
SampleActivity.ktclass SampleActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { val searchView = view.findViewById(R.id.search_view) searchView.setOnQueryTextListener(SearchViewListener()) } // OnQueryTextListenerを、implementしたクラス class SearchViewListener(): OnQueryTextListener { // 入力された文字が変更された際に、呼ばれるメソッド override fun onQueryTextChange(newText: String?): Boolean { println("changed") return false } // 文字の入力後に、検索ボタンが押された際に呼ばれるメソッド override fun onQueryTextSubmit(query: String?): Boolean { println("done") return false } } }これで、何か文字が入力された時や、検索が押された時に、何かしらの処理が実行できます。
- 投稿日:2020-11-04T20:06:08+09:00
#35 Kotlin Koans Properties/Delegates how it works 解説
1 はじめに
Kotlin公式リファレンスのKotlin Koans Properties/Delegates how it worksの解説記事です。
Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。
ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!一度各自で挑戦してから、お目通し頂ければと思います
2 Properties/Delegates how it works の解説
Kotlin Koans Properties/Delegates how it works の解説です。
随時本サイトの内容を引用させていただきます。本文とコードを見てみましょう。
You may declare your own delegates. Implement the methods of the class 'EffectiveDate' so it can be delegated to. Store only the time in milliseconds in 'timeInMillis' property.
Use the extension functions MyDate.toMillis() and Long.toDate(), defined at MyDate.kt
Delegates_how_it_worksimport kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty class D { var date: MyDate by EffectiveDate() } class EffectiveDate<R> : ReadWriteProperty<R, MyDate> { var timeInMillis: Long? = null override fun getValue(thisRef: R, property: KProperty<*>): MyDate { TODO() } override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) { TODO() } }MyDate.ktimport java.util.Calendar data class MyDate(val year: Int, val month:Int, val dayOfMonth: Int) fun MyDate.toMillis(): Long{ val c = Calendar.getInstance() c.set(year,month,dayOfMonth,0,0,0) c.set(Calendar.MILLISECOND,0) return c.getTimeInMillis() } fun Long.toDate(): MyDate { val c = Calendar.getInstance() c.setTimeInMillis(this) return MyDate(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DATE)) }Delegated propertyに利用するクラスを自作し、その中にgetValue()とsetValue()を適切に定義します。
初めに、Delegated property dateに値を利用するとき、
つまりEffectiveDate()クラスのgetValue()を利用するときの実装を考えましょう。
timeInMillisプロパティを利用してMyDateインスタンスを得たいので以下のようになります。
Delegates_how_it_worksoverride fun getValue(thisRef: R, property: KProperty<*>): MyDate { return timeInMillis!!.toDate() }(timeInMillisはnull許容型なので、!!演算子を利用して強制的に非null許容型に変換しています。)
つぎに、Delegated property dateに値を代入するとき、
つまりEffectiveDate()クラスのsetValue()を利用するときの実装を考えましょう。
dateに値(MyDate型)を代入することで、ミリ秒単位の時刻を得たいので、以下のような実装になります。
Delegates_how_it_worksoverride fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) { timeInMillis = value.toMillis() }最終的な実装は以下のようになります。
Delegates_how_it_worksimport kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty class D { var date: MyDate by EffectiveDate() } class EffectiveDate<R> : ReadWriteProperty<R, MyDate> { var timeInMillis: Long? = null override fun getValue(thisRef: R, property: KProperty<*>): MyDate { return timeInMillis!!.toDate() } override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) { timeInMillis = value.toMillis() } }3 最後に
次回はKotlin Koans Builders/Function literals with recieverの解説をします
- 投稿日:2020-11-04T14:50:30+09:00
Apple Developer と Google Play の公式テスターについて
概要
久々に調べて毎回ググるのが面倒だからここにまとめる。
iOS/Androidのアプリ開発で、公式のテスター登録について次の内容となる。※一部公式の内容を抜粋しているため、アップデートがあった際に詳細が異なる可能性があり、この記事をそのまま鵜呑みにせず必ず公式ページを確認するようにお願いします。
TestFlight
内部テスター
- チームでAccount Holder、Admin、App Manager、Developer、Marketingのいずれかの役割を担うメンバーを最大100人まで追加可能。
外部テスター
- Eメールアドレスを使用するか、任意のユーザーに対してAppのテストに参加する機会を開くパブリックリンクを有効にして共有することで、最大10,000人の外部テスターを招待可能。
Play Console
内部テスト版
- メールアドレスを使用して内部テスターのリストを作成できます。内部テストには、アプリごとに最大 100 人のテスターが参加可能。
クローズドテスト版
- メールアドレス
- クローズド テスト版では、メールアドレスを使ってテスターのリストを作成でき、合計 200 件のリストを作成でき、各リストには最大 2,000 人のユーザーを登録が可能。
- リストは 1 トラックにつき最大 50 件作成が可能。
補足
上記は一部の情報のみ抜粋しているためさらに詳細は公式ページを確認してください。
- 投稿日:2020-11-04T14:46:05+09:00
Foreground Service利用時の注意点
- 投稿日:2020-11-04T14:33:01+09:00
[Flutter] [Navigator] 次画面へ複数の値を渡す方法
Navigatorによる画面遷移時に次画面へ値を渡す方法です。
SQLiteやSharedPreferencesで保持する必要はなく、ライトに値を渡したいときにご参考になればと思います。渡したい値が1つの場合
変数 hogeを次画面に渡す例
第3引数のargumentsに変数 hoge をセットします。
遷移元
String hoge = 'hoge'; Navigator.pushReplacementNamed( context, '/next_path', arguments: hoge );遷移先
final String hoge = ModalRoute.of(context).settings.arguments;渡したい値が複数ある場合
変数 hogeId, fuga を次画面に渡す例
渡したい値をまとめたクラスを作成し、そのオブジェクトを渡します。
名前はなんでも良いので、ViewAToBArguments というクラス名で以下のように作成するとします。ViewAToBArguments.dartclass ViewAToBArguments { final int hogeId; final String fuga; ViewAToBArguments(this.hogeId, this.fuga); }第3引数のargumentsに ViewAToBArguments オブジェクトをセットします。
遷移元
int hogeId = 1; String fuga = 'fuga'; Navigator.pushReplacementNamed( context, '/next_path', arguments: ViewAToBArguments(hogeId, fuga) );遷移先
final ViewAToBArguments viewAToBArguments = ModalRoute.of(context).settings.arguments; int hogeId = viewAToBArguments.hogeId; String fuga = viewAToBArguments.fuga;
- 投稿日:2020-11-04T14:26:59+09:00
Android-Kotlin入門記事まとめ
【超初心者向け】Android入門 Hello World編
https://qiita.com/dosukoi_android/items/0d70194a97b625206f40【超初心者向け】Android入門 TextView編
https://qiita.com/dosukoi_android/items/d72c2f6d668ef04206ac【超初心者向け】Android入門 Button編
https://qiita.com/dosukoi_android/items/823e7c293016db1deec3【超初心者向け】Android入門 EditText編
https://qiita.com/dosukoi_android/items/96868f29c061dd46950a【超初心者向け】Android入門 LinearLayout編
https://qiita.com/dosukoi_android/items/197d2704e7ec44cf884b【超初心者向け】Android入門 RecyclerView編
https://qiita.com/dosukoi_android/items/24ba411a02f4b6c3a447
- 投稿日:2020-11-04T14:24:45+09:00
Android記事まとめ5
Androidの動画周りの技術
https://qiita.com/mechamogera/items/d243f52561e928106673AndroidStudioの設定について
https://qiita.com/bowyer-app/items/76e86c7303de8784a8bdAndroidのアップデートn仕組みが変わった
https://pc.watch.impress.co.jp/docs/news/1152404.htmlなぜAndroidエンジニアは少ないのか
https://qiita.com/dosukoi_android/items/19b476dd3823225d4b1dアプリエンジニアからみたピザ屋アプリのUIUX
https://qiita.com/dosukoi_android/items/b793194497f2668a6e8bKotlinでElmの便利関数実装してみた
https://qiita.com/dosukoi_android/items/82477dc6d68c84aa210c
- 投稿日:2020-11-04T14:21:57+09:00
Android記事まとめ4
設定変更画面を作成する公式テンプレート
https://qiita.com/Setz/items/180a41af8ee8cc678ac5
https://maku77.github.io/android/fw/preference-fw.html暗号化されたローカル保存ファイルを安全に管理できる
https://qiita.com/rmorimot/items/ba9e79825bccaa9c0abeKotlinでのスコープ操作
https://speakerdeck.com/kgmyshin/multi-module-no-susume状態管理・オブジェクト指向ならStateパターンを使おう
https://nekogata.hatenablog.com/entry/2013/02/09/233540ModelでのAPI通信などはActivityよりExecuterで監視する
https://qiita.com/teradonburi/items/f2aac85e53f8fa5c79bc
https://qiita.com/KeithYokoma/items/4e6e9bd4e44aab63424d
http://outofmem.hatenablog.com/entry/2014/08/07/061626
https://www.atmarkit.co.jp/ait/articles/1611/25/news019.html
- 投稿日:2020-11-04T14:19:08+09:00
Android記事まとめ3
DataBindingを使うとレイアウト上で他のViewを渡して操作することができる
https://medium.com/@yuzumone/android-databinding-value-of-other-view-75a469f2d31fアプリ内課金のライブラリが新しくなっていた
http://hatesatekite.hatenablog.com/entry/2018/08/07/145422Androidの公式View一覧
https://developer.android.com/reference/android/widget/package-summary.htmlSplash画面のベストプラクティス
https://noknow.info/it/java/android/tips/implement_a_splash_screen_without_activity?lang=jaAndroid Keystore
暗号化キーの管理が安心してできるようになった
https://www.jssec.org/dl/20160323_Akira_Ando.pdf
- 投稿日:2020-11-04T14:16:23+09:00
Android記事まとめ2
Kotlin1.4.0
ラムダのスマートキャストやCorounineDebuggerと引数あり関数の
参照渡しが良さそう
https://qiita.com/sudo5in5k/items/e9207d39fbbfdfe827b2同じチームにいて最高に心強かったエンジニアの特徴まとめ
https://qiita.com/jofuku/items/6420097fd5ff4c44c24dKotlinのListとSequenceって何が違うの?
https://qiita.com/ktzw/items/9aa251a44c11900c8b5fAndroid開発のコードレビュー
botを乗り換えた話
https://techlife.cookpad.com/entry/2017/06/28/190000Navigation Componentでのshared element遷移
https://www.muaaru.com/2019/03/24/post-378/メンバーに恨まれそうな3つのコードレビュー施策を徹底したら
逆にメンバーが爆速で成長した話
https://qiita.com/gakuri/items/f4970aea8de5fa9bf016AndroidのTextViewは重たいのであらかじめ計算しておくと良い
https://medium.com/@star_zero/precomputedtext%E3%82%92%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F-192a3076ac73
- 投稿日:2020-11-04T14:12:13+09:00
Android記事まとめ
Jetpack Composeの画面遷移
https://qiita.com/Nabe1216/items/f329e981f0da76c1d221個人開発・スタートアップで採用すべき最強のアーキテクチャを考えた
https://zenn.dev/yuno_miyako/articles/19201dcb19ff6b6ffc59MvRx(マーベリックス)
https://medium.com/airbnb-engineering/introducing-mvrx-android-on-autopilot-552bca86bd0aReactNativeをやめる話とKotlin Multiplatform
https://www.wantedly.com/companies/wantedly/post_articles/282562DataBingingを使っていてexecutePendingBindingを呼び出さないとどうなるか
https://android.gcreate.jp/358/JetPackComposeの参考資料リスト
https://qiita.com/jiayounokim/items/1f5969969c30079d33efおもしろアニメーションが実装されているアプリ
https://github.com/rodrigomartind/MixAnimationsMotionLayout
- 投稿日:2020-11-04T11:52:39+09:00
Jetpack Compose で縦のDividerを引く
Divider の Composable は存在しますが横線のみで、縦線はなかったので実装してみました。
※Compose 1.0.0-alpha06 時点の話であり、破壊的な変更が入ることがあり得ます。縦線の Composable を用意します。
Modifier にfillMaxHeight
を指定するのを忘れずに。@Composable fun HorizontalDivider( modifier: Modifier = Modifier ) { Spacer( modifier = modifier .preferredWidth(1.dp) .fillMaxHeight() .background(color = MaterialTheme.colors.onSurface.copy(0.12f)) ) }作成した Divider を使うレイアウトで
preferredHeight
にIntrinsicSize.Min
を指定します。Row(Modifier.preferredHeight(IntrinsicSize.Min)) { Text( text = "Label" ) HorizontalDivider() }
IntrinsicSize
を使うことでコンテンツの高さを、コンテンツの最小または最大の固有高さと同じにすることができます。
今回のコードではRow
内のText
の高さを内部の高さとし、fillMaxHeight
を適用することでRow
の高さいっぱいまで表示させることで縦の Divider を実現しています。
- 投稿日:2020-11-04T11:18:05+09:00
Vue3ベースのIonic-Vue(β)で実機デバッグするまで。
Vue3が発表されてIonic-Vueがβで公開されて少し経ったのでどんなもんか触ってみました。
諸事情あってWindowsで開発環境を構築していますがMacでもほぼ差異なく動きましたionic/cliをglobalにinstallします。
npm install -g @ionic/cli@testingmy-appはプロジェクト名なので任意に
ionic start my-app tabs --type vue --tag vue-beta1分程待つと
Your Ionic app is ready! Follow these next steps: - Go to your new project: cd ./vocbook - Run ionic serve within the app directory to see your app in the browser - Run ionic capacitor add to add a native iOS or Android project using Capacitor - Generate your app icon and splash screens using cordova-res --skip-config --copy - Explore the Ionic docs for components, tutorials, and more: https://ion.link/docs - Building an enterprise app? Ionic has Enterprise Support and Features: https://ion.link/enterprise-editionionic serveすると無事動作は確認できました!
Androidアプリとしての開発をしたいので一旦
npm run build
します
ここも特に問題なく正常終了。dist配下に諸々生成されるのでnpx cap add androidまたは
capacitor.cmd add androidでAndroidのネイティブプロジェクトを作ります。
? What platform would you like to add? android > capacitor.cmd add android √ Installing android dependencies in 24.90s √ Adding native android project in: √ Syncing Gradle in 652.80μp √ add in 24.97s √ Copying web assets from dist to android\app\src\main\assets\public in 112.61ms √ Copying native bridge in 3.06ms √ Copying capacitor.config.json in 4.43ms √ copy in 146.39ms √ Updating Android plugins in 9.65ms Found 0 Capacitor plugins for android: √ update android in 42.47ms Now you can run npx cap open android to launch Android StudioAndroid Studioで開けといわれるので確認します
npx cap open androidで自動的にAndroid Studioが起動するのでgradleのsyncなんかを済ませて…
実機で動作しました!
まだ全然詳細は見れていないですがmanifestのパーミッションがもりもりになっていて、使う予定がないものもがっつり入っているので検証時は楽ですがリリース時には見直しが必要そうです。
<uses-permission android:name="android.permission.INTERNET" /> <!-- Camera, Photos, input file --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Geolocation API --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.location.gps" /> <!-- Network API --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Navigator.getUserMedia --> <!-- Video --> <uses-permission android:name="android.permission.CAMERA" /> <!-- Audio --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>ほぼドキュメント通りでハマりどころもなく実機検証までできたので、このペースでβが外れてくれるとうれしいですね。
- 投稿日:2020-11-04T02:31:15+09:00
Firebase Cloud Messagingでトークンの取得方法が変わっていた
タイトルのとおり。
com.google.firebase:firebase-messaging.20.3.0 からはFirebaseInstanceId
クラスのgetInstanceId
関数からではなく、FirebaseMessaging
クラスのgetToken
関数から取得するようになったようだ。// 1. リスナーで非同期的に取得するやり方 FirebaseMessaging.getInstance().token.addOnCompleteListener { task -> if (!task.isSuccessful) { return@OnCompleteListener } val token = task.result } // 2. kotlinx-coroutines-play-servicesを使ってコルーチン内で同期的に取得するやり方 val token = FirebaseMessaging.getInstance().token.await()参考:
com.google.firebase:firebase-messaging.20.3.0
より前の書き方( deprecated )// 1. リスナーで非同期的に取得するやり方 FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task -> if (!task.isSuccessful) { return@addOnCompleteListener } val token = task.result?.token } // 2. kotlinx-coroutines-play-servicesを使ってコルーチン内で同期的に取得するやり方 val token = FirebaseInstanceId.getInstance().instanceId.await().token「親クラス(FirebaseInstanceId)が持つinstanceId、の中にあるtoken」から「親クラス(FirebaseMessaging)が持つtoken」に変わっているのがハマりポイントかも。