20201104のAndroidに関する記事は14件です。

【Android】SearchView 使ってみた

【Android】SearchView 使ってみた

SearchViewとは

文字を入力してもらうような検索レイアウトを作るのって、面倒だなと思ってたら、もともと用意されているレイアウトで、SearchViewというものがありました。

SearchViewについての公式ドキュメント

  • SearchViewの例

スクショ.png

使い方

使い方はとても簡単です。

  • レイアウト
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.kt
class 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
        }
  }
}

これで、何か文字が入力された時や、検索が押された時に、何かしらの処理が実行できます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

#35 Kotlin Koans Properties/Delegates how it works 解説

1 はじめに

Kotlin公式リファレンスのKotlin Koans Properties/Delegates how it worksの解説記事です。

Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。

ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!

一度各自で挑戦してから、お目通し頂ければと思います:fist:

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_works
import 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.kt
import 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_works
 override fun getValue(thisRef: R, property: KProperty<*>): MyDate {
        return timeInMillis!!.toDate()
 }

(timeInMillisはnull許容型なので、!!演算子を利用して強制的に非null許容型に変換しています。)

つぎに、Delegated property dateに値を代入するとき、

つまりEffectiveDate()クラスのsetValue()を利用するときの実装を考えましょう。

dateに値(MyDate型)を代入することで、ミリ秒単位の時刻を得たいので、以下のような実装になります。

Delegates_how_it_works
override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) {
       timeInMillis = value.toMillis()
}

最終的な実装は以下のようになります。

Delegates_how_it_works
import 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の解説をします:muscle:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Apple Developer と Google Play の公式テスターについて

概要

久々に調べて毎回ググるのが面倒だからここにまとめる。
iOS/Androidのアプリ開発で、公式のテスター登録について次の内容となる。

※一部公式の内容を抜粋しているため、アップデートがあった際に詳細が異なる可能性があり、この記事をそのまま鵜呑みにせず必ず公式ページを確認するようにお願いします。

TestFlight

 lockup-hero-large_2x.png

内部テスター

  • チームでAccount Holder、Admin、App Manager、Developer、Marketingのいずれかの役割を担うメンバーを最大100人まで追加可能。

外部テスター

  • Eメールアドレスを使用するか、任意のユーザーに対してAppのテストに参加する機会を開くパブリックリンクを有効にして共有することで、最大10,000人の外部テスターを招待可能。

Play Console

 maxresdefault.jpg

内部テスト版

  • メールアドレスを使用して内部テスターのリストを作成できます。内部テストには、アプリごとに最大 100 人のテスターが参加可能。

クローズドテスト版

  • メールアドレス
    • クローズド テスト版では、メールアドレスを使ってテスターのリストを作成でき、合計 200 件のリストを作成でき、各リストには最大 2,000 人のユーザーを登録が可能。
    • リストは 1 トラックにつき最大 50 件作成が可能。

補足

上記は一部の情報のみ抜粋しているためさらに詳細は公式ページを確認してください。

 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Foreground Service利用時の注意点

Android開発を始めて間もないため、ちょっとしたことで躓いてしまうのですが、ForegroundServiceでハマってしまいました。

API Level 28 以上の場合の対応

Manifestファイルに追記が必要でした。これがなかったため、Service開始時にアプリが落ちていました。

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

参考

Foreground Serviceの基本
Android 9 Pie 時代のフォアグラウンドサービス

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[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.dart
class 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;
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android記事まとめ5

Androidの動画周りの技術
https://qiita.com/mechamogera/items/d243f52561e928106673

AndroidStudioの設定について
https://qiita.com/bowyer-app/items/76e86c7303de8784a8bd

Androidのアップデート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/b793194497f2668a6e8b

KotlinでElmの便利関数実装してみた
https://qiita.com/dosukoi_android/items/82477dc6d68c84aa210c

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android記事まとめ4

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android記事まとめ3

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android記事まとめ2

Kotlin1.4.0
ラムダのスマートキャストやCorounineDebuggerと引数あり関数の
参照渡しが良さそう
https://qiita.com/sudo5in5k/items/e9207d39fbbfdfe827b2

同じチームにいて最高に心強かったエンジニアの特徴まとめ
https://qiita.com/jofuku/items/6420097fd5ff4c44c24d

KotlinのListとSequenceって何が違うの?
https://qiita.com/ktzw/items/9aa251a44c11900c8b5f

Android開発のコードレビュー
botを乗り換えた話
https://techlife.cookpad.com/entry/2017/06/28/190000

Navigation Componentでのshared element遷移
https://www.muaaru.com/2019/03/24/post-378/

メンバーに恨まれそうな3つのコードレビュー施策を徹底したら
逆にメンバーが爆速で成長した話
https://qiita.com/gakuri/items/f4970aea8de5fa9bf016

Androidの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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android記事まとめ

Jetpack Composeの画面遷移
https://qiita.com/Nabe1216/items/f329e981f0da76c1d221

個人開発・スタートアップで採用すべき最強のアーキテクチャを考えた
https://zenn.dev/yuno_miyako/articles/19201dcb19ff6b6ffc59

MvRx(マーベリックス)
https://medium.com/airbnb-engineering/introducing-mvrx-android-on-autopilot-552bca86bd0a

ReactNativeをやめる話とKotlin Multiplatform
https://www.wantedly.com/companies/wantedly/post_articles/282562

DataBingingを使っていてexecutePendingBindingを呼び出さないとどうなるか
https://android.gcreate.jp/358/

JetPackComposeの参考資料リスト
https://qiita.com/jiayounokim/items/1f5969969c30079d33ef

おもしろアニメーションが実装されているアプリ
https://github.com/rodrigomartind/MixAnimationsMotionLayout

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 を使うレイアウトで preferredHeightIntrinsicSize.Min を指定します。

Row(Modifier.preferredHeight(IntrinsicSize.Min)) {
    Text(
        text = "Label"
    )
    HorizontalDivider()
}

IntrinsicSize を使うことでコンテンツの高さを、コンテンツの最小または最大の固有高さと同じにすることができます。
今回のコードでは Row 内の Text の高さを内部の高さとし、fillMaxHeight を適用することで Row の高さいっぱいまで表示させることで縦の Divider を実現しています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue3ベースのIonic-Vue(β)で実機デバッグするまで。

Vue3が発表されてIonic-Vueがβで公開されて少し経ったのでどんなもんか触ってみました。
諸事情あってWindowsで開発環境を構築していますがMacでもほぼ差異なく動きました

ionic/cliをglobalにinstallします。

npm install -g @ionic/cli@testing

my-appはプロジェクト名なので任意に

ionic start my-app tabs --type vue --tag vue-beta

1分程待つと

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-edition
ionic serve

すると無事動作は確認できました!

image.png

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 Studio

Android Studioで開けといわれるので確認します

npx cap open android

で自動的にAndroid Studioが起動するのでgradleのsyncなんかを済ませて…

実機で動作しました!

Screenshot_20201104-110441.png

まだ全然詳細は見れていないですが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"/>

ほぼドキュメント通りでハマりどころもなく実機検証までできたので、このペースでβが外れてくれるとうれしいですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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」に変わっているのがハマりポイントかも。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む