こんばんは、 id:takuji31 です。
今日はSupport Library 25.0.0 で追加されたBottomNavigationViewを使ってみたので紹介します。
※これは本日開催の関西モバイルアプリ研究会 #19 で発表した内容です。
続きを読むこんばんは、 id:takuji31 です。
今日はSupport Library 25.0.0 で追加されたBottomNavigationViewを使ってみたので紹介します。
※これは本日開催の関西モバイルアプリ研究会 #19 で発表した内容です。
続きを読むめっちゃ雑なメモ。
今いるチームではTODOは"必ずやらなければならないこと"にだけ付けるというルールがあって、だいたいshibayuさんのブログの通りに運用してる。
最近コード中のTODOコメントの書き方を工夫している - $shibayu36->blog;
自分の場合割とGitのbranch名に機能名とかをprefixとしてつけいるので、TODO(feature-phase)的なTODOを延々と量産してはやったら消すし、やってないなら残したままmergeして適切なタイミング(リリース前とか次のbranchとか)で消すようにしている。
残っているTODOを確認するのも TODO(feature
をgit grepなりagなりで検索すればよい。
割と量産するので、TODO(branch-name)を毎回打つの面倒だし、コピペするのも行ごとってわけじゃなくてやはり面倒なので、勝手にbranch名取ってきて挿入してくれるneosnippetのスニペットを書いた。
snippet todo options head # TODO(`substitute(system('git rev-parse --abbrev-ref HEAD'), '\n\+$', '', '')`) : ${0}
これでtodoを展開すると# TODO(feature-phase) :
みたいなのができあがって便利。
git管理下以外では動かないけど、そもそもそういうところで使わないので気にしていない。
こんばんは、最近はAndroid JavaではなくPerlとTypeScriptを書いているid:takuji31です。
この記事は本日開催の関西モバイルアプリ研究会 #17の発表を元に作成しています。
今日はSupport Library 24.2.0でrecyclerview-v7に追加された DiffUtil
を試してみたので紹介します。
2つの List
の差分を計算するユーティリティー。
List
の要素ごとの変化を計算する DiffUtil.Callback
を引数に取り、 DiffUtil.DiffResult
を受け取る。
デフォルトでは追加と削除と更新のみ受け取れるが、オプション指定することで移動も計算できる。ただし、計算コストが上がる。
それぞれの要素の変化を DiffUtil
に伝えるCallback。5つのメソッドが用意されていて、4つがabstractになっている。
名前通り新しい/古い List
のサイズを返す。
2つのアイテムが同じものであるかどうかを判定する。
例えば2つの List
にユーザーのエンティティーが入っていると仮定して、それぞれのユーザーが同一のものかをこのメソッドで判定してやる。
areItemsTheSame
が true
だった時に呼ばれる。
areItemsTheSame
はアイテムそのものが同じものであるかどうかの判定だったが、 areContentsTheSame
はアイテムの内容が同じかどうかを判定する。
見た目上なんらかの変化があれば false
を返す。
areContentsTheSame
が false
だった時に呼ばれる。
古いアイテムと新しいアイテムで、どういった変更があったか通知するオブジェクトを生成する。
通知するオブジェクトの型は自由なので、変更通知用のクラスを作ってそのオブジェクトを渡すイメージ。
このメソッドだけabstractになっていないので、実装しなくてもよい。その場合は null
が渡される。
DiffUtil.DiffResult
は計算したdiffの結果を保持している。直接結果を読むことはできず、 ListUpdateCallback
あるいは RecyclerView.Adapter
を経由して取得する。
RecyclerView.Adapter
に新しいデーターを渡した後に DiffResult.dispatchUpdatesTo(RecyclerView.Adapter adapter)
を呼ぶことで、 RecyclerView
の変更通知に使える。
※いつも通りKotlinです
DiffUtil
はrecyclerview-v7の24.2.0以降に入っているので、入れておく。
雑にModelを作る
enum class Status { INTERESTED, LIKE, LOVE; } data class Artist(val name: String, val status: Status) { companion object { val list: List<Artist> = listOf( Artist(name = "小倉唯", status = LOVE), Artist(name = "雨宮天", status = LOVE), Artist(name = "水瀬いのり", status = LIKE), Artist(name = "Trysail", status = LIKE), Artist(name = "Minami", status = LIKE), Artist(name = "佐倉綾音", status = LOVE), Artist(name = "田村ゆかり", status = INTERESTED), Artist(name = "ワルキューレ", status = INTERESTED), Artist(name = "水樹奈々", status = INTERESTED) ) } }
DiffUtil.Callback
の実装を作る、匿名クラスでも問題ないが、ちゃんとクラス化しておくと使い回せるのでよさそう。
class DiffCallback(val oldList: List<Artist>, val newList: List<Artist>) : DiffUtil.Callback() { override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition].name == newList[newItemPosition].name } override fun getOldListSize(): Int { return oldList.size } override fun getNewListSize(): Int { return newList.size } override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { return oldList[oldItemPosition] == newList[newItemPosition] } override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Pair<Status, Status> { return Pair(oldList[oldItemPosition].status, newList[newItemPosition].status) } }
このケースでは name
をIDととらえて、 name
が同じなら同じアイテムで、かつ他のプロパティー(といっても status
だけだが)が一致した場合に同じコンテンツとみなしている。
あとは適当に RecyclerView.Adapter
やら Activity
やら必要なものを実装してやって、リストの更新をするときに以下のように実行してやる。
fun updateItems(items : List<Artist>) { val oldItems = adapter.items val diffResult = DiffUtil.calculateDiff(DiffCallback(oldList = oldItems, newList = items), true) adapter.items = items diffResult.dispatchUpdatesTo(adapter) }
するといい感じにリストの更新がアニメーションされる。
RecylerView
以外と組み合わせる、Change payloadの中身を見て何かしたい、などといった場合は ListUpdateCallback
と組み合わせて使うこと。
List
と新しい List
の中身を比較するので、 List
の要素が変わる、あるいは要素そのものの値が自動更新されるような仕組み(Realmとか)とは一緒に使えなさそうList
の要素数は2^26(=67108864)までDiffUtil
を使うことで RecylerView
への詳細な更新通知が楽になるDiffResult.dispatchUpdatesTo(RecyclerView.Adapter adapter)
呼ぶだけでよいRecylerView
以外との組み合わせなど凝ったことをやりたい時は ListUpdateCallback
を使うサンプルコードはGithubにあげてます。
こんにちは、id:takuji31です。
以前告知していた関西Kotlin勉強会 #3改め、Kansai.kt #1を7/9(土)に開催します!
↓↓↓↓↓↓申し込みはこちら↓↓↓↓↓↓
トーク枠とLT枠もまだ若干空きがありますので、お気軽にご応募ください!
参加おまちしております。
おはようございます、id:takuji31です。
4月2日(土)にはてな京都オフィスで開催された「Kotlin 1.0リリース記念勉強会 in 京都」でも告知しましたが、関西Kotlin勉強会 #3を開催します!
続きを読む