BottomSheetカスタムあれこれ
supportLibraryにBottomSheetDialogFragmentというのがあります。 これは下からスッと出てくるダイアログもどきで コンテンツの共有やGoogleMapアプリなどで使われています。
このBottomSheetDialogFragmentを使用する際 独自の動作部分をカスタマイズ出来るのでメモ代わりに残します。
表示後STATE_EXPANDED(全て表示)にしたい!
通常は一部分のみ表示され、上へスワイプすることで全域を見ることが出来るが 初めから全域を表示させたい時。
onCreateDialogをOverrideし setOnShowListenerでStateをEXPANDEDに変える
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) dialog.setOnShowListener { val d = dialog as BottomSheetDialog val bottomSheet = d.findViewById(android.support.design.R.id.design_bottom_sheet) as FrameLayout val behavior = BottomSheetBehavior.from(bottomSheet) behavior.state = BottomSheetBehavior.STATE_EXPANDED } }
COLLAPSEDを無効にしたい!
一部分のみ見えてる状態をなくしたい時。
EXPANDEDと組み合わせると全画面ダイアログになります。
DialogFragmentでやれ
やっぱりonCreateDialogをoverrideし BottomSheetCallbackを設定する
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) dialog.setOnShowListener { val d = dialog as BottomSheetDialog val bottomSheet = d.findViewById(android.support.design.R.id.design_bottom_sheet) as FrameLayout val behavior = BottomSheetBehavior.from(bottomSheet) behavior.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onSlide(bottomSheet: View, slideOffset: Float) { } override fun onStateChanged(bottomSheet: View, newState: Int) { //Drag,Collapsedの時はExpandedにする if (newState == BottomSheetBehavior.STATE_DRAGGING || newState == BottomSheetBehavior.STATE_COLLAPSED) { behavior.state = BottomSheetBehavior.STATE_EXPANDED } } }) } }
[所要時間:8分]
3回調べたらメモに残そう
コードを書く上でparcelableの実装とかdrawableで使用できるタグとか ちょっとしたことだけどそのたびにググってることは結構あると思う。 そういったのはメモに残していつでも取り出せるようにしておくと便利。 そのメモを元にブログの記事に出来たりするし。 (このブログが荒いのはメモが元なのもある)
自分はQuiverというメモアプリに残して書き溜めてます。
FreeTrial版もあるのでまずはお試しすることをオススメします。
メモを残す上で大事なのは検索性を考えること。 タグや本文にできるだけヒットする単語を仕込んでおきましょう。 でないと肝心な時に取り出せないで結局調べ直す羽目になる。
[所要時間:10分]
Toolbarの戻るボタンを変える
なんてことないネタですが
appCompatActivityを継承していれば 以下のメソッドで矢印のアイコンを変更することができる。
supportActionBar?.setHomeAsUpIndicator(resourceID or Drawable)
通常
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_email_black_24dp);
[所要時間:6分]
FCMの疎通テスト
Firebaseネタ。
Firebase Notificationsで通知のテストを行いたい時 手元のターミナルからリクエストを送れば ちゃんと送信されます。 これは送る型は決まっているがバックエンドが間に合ってないときや 送る条件を満たすのが煩雑な時に役に立ちます。(やりたいことは通知を受取適切に処理しているか、なので)
使えるパラメーターは以下を参考にして下さい。 https://firebase.google.com/docs/cloud-messaging/http-server-ref#-http-json
またAuthorizationのValueはFirebaseCPから取得してください。
以下curlとhttpieのコマンドです。 data部分にペイロードを記述します。
curl
curl --header "Authorization:key=abcdefg12345678" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send -d '{"to":"端末のID"}' '{"data":{"score":"3x1"}}'
httpie
http -v POST https://fcm.googleapis.com/fcm/send Authorization:key=abcdefg12345678 to=端末のID data={"score":"3x1"}
(ペイロードがちょっと怪しいかも間違ってたらすみません)
[所要時間:10分]
Launcherを複数持つ
androidのちょっとした小ネタ。 開発中では何度も同じ画面を行き来することになるが 階層が深くなると時間のロスも出てきて勿体無い。
そこでAndroidManifest内のActivityタグに intentFilterを記述すれば、そのActivityから立ち上げる事が出来るので 時間の節約になるし動作テストも快適になる。 ただしリリース時には必ず消すこと。
<application> ~~~~~ <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter android:label="@string/app_name"> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity>[f:id:suwashimizu:20171121094101p:plain] <activity android:name=".SubActivity" android:screenOrientation="portrait" android:label="SampleTest"> <intent-filter android:label="@string/app_name"> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application>
2つのLauncherを持つことができた
[所要時間:12分]
あなたはJavaでオブジェクト指向開発ができないのかを読んだよ
寝る前にコツコツと読みました。
なぜ、あなたはJavaでオブジェクト指向開発ができないのか―Javaの壁を克服する実践トレーニング
- 作者: 小森裕介,アクロクエストテクノロジー株式会社
- 出版社/メーカー: 技術評論社
- 発売日: 2004/12/01
- メディア: 単行本
- 購入: 10人 クリック: 217回
- この商品を含むブログ (50件) を見る
オブジェクト指向って?から始まり 中盤からはじゃんけんゲーム・トランプゲームを題材にして オブジェクト指向(以降OOP)について学ぶ内容。
javaを学びながらOOPではなく、javaの基本が分かってる人向け。 なのでプログラミング始めました!って人が最初に読む本ではなく ある程度作れるようになったけどソースコードがスパゲッティ スッキリ書けないと悩んでる人やOOPについて再考したい人向け。
全体を把握する必要性や、抽象化への落とし込みの手順について書かれているので これからの考えをまとめるのに役立ちそう。 OOPは現実をモデリングするが必ずしも現実と合わせる必要はないのは確かになあと思った。 例えばじゃんけんゲームではゲームマスタークラスとプレイヤークラスを作成するが 勝利を宣言するのはプレイヤークラスの責務で 審判は勝利宣言を受け取るだけ。 普通に作ると審判側で勝利の判定を行ってしまいそうだが 確かにプレイヤーで宣言したほうが分かりやすい。 プログラムは嘘つかないから虚偽宣言とか考えなくて良いわけだ。
最終章はトランプゲームのフレームワーク作りだったので これを元に派生するトランプゲームを作るのも面白そう。 大富豪とか大富豪とか
同じジャンルの本を纏めて読むと学習効率良いとのことなので 他にも読んでみようかな
RxでHotObservableとFilter
RxにはHotObservableとColdObservableがある。 HotObservableについてはそんなもんなあるなーぐらいで 実際に使う機会がなく、あまり理解できてなかった。
rxの使用用途がretrofitを介してのAPIとのやりとりが主だったのも大きい。
んで触る必要が出てきたのでどう動くのかテストしてみた所
@Test fun filterTest() { val publisher = PublishSubject.create<String>() publisher.onNext("abc") publisher.onNext("777") //数値のみを出力する val numberObserver = publisher.filter { try { it.toInt() true } catch (e: NumberFormatException) { false } }.map(String::toInt) //10文字以上の文字列を出力する val longTextObserver = publisher.filter { it.length >= 10 } longTextObserver.subscribe(this::printText) numberObserver.subscribe(this::printNum) publisher.onNext("123") publisher.onNext("BBB") publisher.onNext("BBBBBBBBBBBBBBBBBBBBBBBB") publisher.onNext("1111111111") publisher.onNext("11111111111111111111111111111111") } fun printNum(num: Int) { println("num:$num") } fun printText(text: String) { println("text:$text") }
結果がこれ
output num:123 text:BBBBBBBBBBBBBBBBBBBBBBBB text:1111111111 num:1111111111 text:11111111111111111111111111111111
HotObservable#onNext(value)で値を流す。 HotObservable#subscribeした後から流した値が受け取れる。: abc,777は出力されない。 HotObservable#filterやmapなどで別のObservableを生成することが出来る。: numberFilterやlongTextFilterがそれ HotObservable#filterで生成したObservableをSubscribeすれば特定のフィルタリングした値だけを受け取れる。 ちなみにちゃんと購読解除処理書かないと参照持ち続けるので注意しよう。
ということはjsonを受け取って、様々な型に変換し特定の型だけ流すObservableも生成できるということか! この辺は本で読んだけだったので理解が深まった。 触らないとダメやね。