- 投稿日:2020-08-09T17:09:17+09:00
ShapeableImageViewで真ん丸や角丸の画像を手軽に作ってみる
真ん丸や角丸の画像を作る方法としてPiccasoなどのライブラリを使う方法1や、手軽な方法としてCardViewを用いたやり方2などがありますが、Material Components 1.2.0に追加された
ShapeableImageView
を使ったやり方を紹介してみます。下のような画像を手軽に作成できます。
準備
Material Components 1.2.0を追加しておきます。
dependencies { implementation "com.google.android.material:material:1.2.0" }使い方
使い方としては、styleを定義して
ShapeableImageView
のapp:shapeAppearanceOverlay
属性に指定してやるだけでOKです。以下で詳しく見ていきます。真ん丸
styles.xml
に以下を追加。
cornerFamily
にrounded
、cornerSize
に50%を指定してあります。<style name="circleImageView" parent=""> <item name="cornerFamily">rounded</item> <item name="cornerSize">50%</item> </style>あとはレイアウトファイルに
ShapeableImageView
を配置してapp:shapeAppearanceOverlay
属性に上記のスタイルを指定してやります。<com.google.android.material.imageview.ShapeableImageView android:layout_width="100dp" android:layout_height="100dp" android:adjustViewBounds="true" android:src="@drawable/ic_droid" app:shapeAppearanceOverlay="@style/circleImageView" />角丸
cornerSize
を調整してやれば角丸にできます。
今回は24%にしてみました。<style name="roundedCornersImageView" parent=""> <item name="cornerFamily">rounded</item> <item name="cornerSize">24%</item> </style>ひし形
cornerFamily
にcut
を指定し、cornerSize
を50%にすればひし形にできます。<style name="diamondImageView" parent=""> <item name="cornerFamily">cut</item> <item name="cornerSize">50%</item> </style>部分的に適応
四隅の一部のみを変えることも可能です。
例えば左上をround、右下をcutにするには以下のように指定してやります。
指定できる属性名についてはhttps://material.io/develop/android/theming/shapeに載ってます。<style name="mixImageView" parent=""> <item name="cornerFamilyTopLeft">rounded</item> <item name="cornerFamilyBottomRight">cut</item> <item name="cornerSizeTopLeft">28%</item> <item name="cornerSizeBottomRight">24%</item> </style>手軽に真ん丸や角丸などの画像を作成できました!
以上です。参考にしたサイト
- 投稿日:2020-08-09T16:09:35+09:00
【Android/Kotlin】インターネット接続の確認とNetworkInfo非推奨の解消
開発環境
- macOS 10.15.5
- Android Studio 4.0
- Kotlin 1.3.72
やりたいこと
サーバーとの通信の前に端末がインターネットに接続されているかどうかを確認したい。
NetworkInfo
を使う方法デベロッパーガイドの接続ステータスの特定と監視(2020/08/09アクセス)によると、
ConnectivityManager
を使用すれば、インターネットに接続されているか、接続されている場合はどのようなタイプかを確認できるそうです。ということで、ボタンが押されると接続状況が確認され、接続のタイプを表示する簡単な実装を行いました。
(マニフェストファイルにパーミッションを追加するのを忘れないようにしましょう)AndroidManifest.xml<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />MainActivity.ktval text = findViewById<TextView>(R.id.textView) val button = findViewById<Button>(R.id.button) button.setOnClickListener { val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val activeNetwork: NetworkInfo? = cm.activeNetworkInfo val isConnected: Boolean = activeNetwork?.isConnectedOrConnecting == true val connectionType = activeNetwork?.type if (isConnected) { text.text = when (connectionType) { ConnectivityManager.TYPE_WIFI -> "Wifiに接続しています" ConnectivityManager.TYPE_MOBILE -> "モバイル通信に接続しています" else -> "その他のネットワークに接続しています" } } else { text.text = "インターネットに接続していません" } }以上のようにすればインターネットの接続が確認できますが、APIレベル29で
ConnectivityManager.getActiveNetworkInfo()
とNetworkInfo
が非推奨となったため、AndroidStudioでは取り消し線が引かれてしまいます。
これを解消するためにNetworkInfo
クラスの代わりにConnectivityManager.getNetworkCapabilities()
を使うことにします。
ConnectivityManager.getNetworkCapabilities()
を使う方法
NetworkCapabilities
はアクティブなネットワークの能力を表すクラスです。
以下のように実装できるかと思います。MainActivity.ktbutton.setOnClickListener { // ConnectivityManagerの取得 val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager // NetworkCapabilitiesの取得 // 引数にcm.activeNetworkを指定し、現在アクティブなデフォルトネットワークに対応するNetworkオブジェクトを渡している val capabilities = cm.getNetworkCapabilities(cm.activeNetwork) if (capabilities != null) { text.text = when { capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> "Wifiに接続しています" capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> "モバイル通信に接続しています" else -> "その他のネットワークに接続しています" } } else { text.text = "インターネットに接続していません" } }*
NetworkCapabilities
はAPI21、ConnectivityManager.getActiveNetwork()
API23で追加されたので、APIレベル23以上必要です参考
- はてなブログの記事 「Android 10 時代の Connectivity Monitoring 」(2020/08/09アクセス)
- Android - ネットワーク(WIFI)の接続状態を確認し、変更の検出 (2020/08/09アクセス)
を参考にさせていただきました。
- 投稿日:2020-08-09T11:15:38+09:00
MemuエミュレーターにXposedを入れてみた
XposedをMemuエミュレーターに入れるには
MemuエミュレーターにXposedを入れてみた。
基本的にしたのURLに方法は書いていますが
https://www.memuplay.com/blog/xposed.htmlこの#6 Go into terminal emulatorがどこにあるのかわからなかったのでメモします
注意:
MemuエミュレーターはデフォルトでAndroidバージョン7です(2020/8/9現在)
なので上記サイトではxposed-v85-sdk22-x86を入れていますが
xposed-v89-sdk25-x86を入れてください環境はWindows10です
where Memu >>> C:\Program Files (x86)\Microvirt\MEmu\MEmu.exe cd C:\Program Files (x86)\Microvirt\MEmu memuc.exe -i 0 execcmd cd /storage/emulated/0/Download/xposed-v85-sdk22-x86/;sh flash-script.sh-i 0(インデックス番号)はエミュレーターを指定するものです-n (エミュ名)でも代替可
execcmdでExecします/storage/emulated/0/Download/xposed-v85-sdk22-x86
は解凍したXposedフレームワークのPATHを
;sh flash-script.sh
で実行します1行で書いてるのは
動かすたびに毎回入力がリセットされるからですC:\Program Files (x86)\Microvirt\MEmu>memuc.exe -i 0 execcmd pwd / C:\Program Files (x86)\Microvirt\MEmu>memuc.exe -i 0 execcmd cd storage C:\Program Files (x86)\Microvirt\MEmu>memuc.exe -i 0 execcmd pwd /こうなります:(
ほかにいい方法があるのかもしれませんが
ちゃんと動いてるのでよし!追記
Shell 開けました
memuc.exe -i 0 adb shell
- 投稿日:2020-08-09T00:24:22+09:00
KotlinのJUnitTestにおけるアサーションライブラリはKluentがとても良い感じ
JUnitのアサーションを快適に書きたい
KotlinでUnitTestを書いていて、今までさして調べずメジャーだからと言う理由でHamcrestを使ってたんですが、もともとJavaのライブラリなのでKotlinだと微妙に使いにくい部分がありました。
例えば型判定のアサーションを記述したいときは↓のように書きますが
val value = 10 assertThat(value, `is`(instanceOf(Int::class.java)))Kotlinでは
is
が予約語に指定されているため`
で括る必要もあるのと、is
とinstanceOf
がネストしているのも微妙に書きにくい&読みにくく、クラス指定も::class.java
まで記述する必要があって、当たり前ですがKClass
で記述できないのでJavaの世界観に引きづられている印象を受けます。また細かいところだと、
is
メソッド一つとってもHamcrest内だけでも3つimoport
候補が出てきて、どれをimoport
するんだっけ?と一瞬手が止まるのも書きにくいなぁと思っていた部分でした(ここはKotlin関係ない部分ですが)
この辺はイマイチだなーと思いつつプロダクションに入らないコードだし動けばまあいいかと思っていたんですが、Kotlinに特化したアサーションライブラリを試しに使ってみたら思いの外快適に記述できて感動したので紹介します。
Kluent
Docs: https://markusamshove.github.io/Kluent/
Github: https://github.com/MarkusAmshove/KluentKluentはKotlinに特化したJunitアサーションライブラリです。
Fluent Assertion-Library for Kotlin
とあるように流れるように記述できるのが特徴です。Hamcrestがstaticメソッドを軸にアサーションを実装しているのに対し、KluentはKotlinの拡張関数やinfix記法(中置記法)を軸にアサーションが実装されています。
アサーション比較
公式サイトへのリンク先に使い方がわかりやすく乗っているのでぱっと見で理解できるとは思いますが、1例として上記で扱った型判定のアサーションでHamcrestとKluentを比較してみます。
Hamcrestval value = 10 assertThat(value, `is`(instanceOf(Int::class.java)))Kluentval value = 10 value shouldBeInstanceOf Int::classどうでしょうか、カッコもなくなりだいぶ読みやすく書きやすくなったと思います。
Hamcrestはstaticメソッドである関係上Utilクラスのように手前にassertThat
メソッドを書かなくてはいけませんが、Kluentはinfix記法のおかげで「valueはint型でなければならない」という英文を違和感なく構築することができています。もちろんinfix記法でも補完が効きます。とりあえず
should...
と打てば必要なものが見つかると思います。
また、infix以外にも拡張関数で定義されたアサーションもあり、nullチェックなどがそれに当たります。
Hamcrestval value = 10 assertThat(value, `is`(notNullValue()))Kluentval value: Int? = 10 value.shouldNotBeNull()そらで書く場合どちらのほうが記述しやすいかは一目瞭然ですね!
私自身Kluentの基本的な機能しかまだ使っていませんが、サイトのドキュメントを見る限り一般的にアサーションで最低限必要とされるものは揃っていると思います。モック機能
KluentにはMocking機能があり、サイト内の解説によるとMockito-Kotlinのラッパーとしての役割も担っているそうです。
Kluentval mock = mock(Database::class) mock.getPerson(1)私はMockKに慣れきっていたので使いませんでしたがMockito-Kotlinを使っている方であれば嬉しいポイントかもしれません。
Androidで使う場合
これは正直ちゃんとはわからなかった部分だったのですが、GithubのドキュメントによるとAndroidで使う場合にはartifactが異なり、以下を指定する必要があるそうです。
build.gradle// for JVM: testImplementation 'org.amshove.kluent:kluent:{version}' // for Android: testImplementation 'org.amshove.kluent:kluent-android:{version}'この違いについてはドキュメントには記載がなかったのですが、2020/08/08現在のリポジトリ内をざっくり検索したところライブラリの機能や含まれているソースコード自体には違いはなく、JVMによる実行環境とAndroid上の実行環境の差異を吸収するためにartifactが別れているようでした。
これが正しければですが、Androidデバイス上で実行されるInstrumented Testは
org.amshove.kluent:kluent-android
を使う必要がありますが、Androidのプロジェクトであってもデバイスを伴わずPC上のJVM環境で実行されるUnitTestやRobolectricを使ったテストはorg.amshove.kluent:kluent
で十分と思われます。まとめ
Kluentはいいぞ!