#12月1日は「データセンターの日」とのことで……
今日は何の日によると、12月1日は「データセンターの日」という記念日だそうな。Data CenterとDeCemberが雰囲気似ているという理由から、ソフトバンクIDC(現IDCフロンティア)が制定したんだとか。
というわけで、「データ」にまつわるAndroid
CafeSnapというアプリでは、Design Support Libraryを使用して、マテリアルデザインを導入しつつあります。マテリアルデザインの設計思想では、これまでのOSより自由で、魅力的なモーションを用いたUIが、比較的簡単に実装できるようになりました。
今日は、マテリアル化をすすめる中で遭遇した、RecyclerViewに渡すデータの「更新」に関するメソッドを、まとめてみることにします。
そもそもRecyclerViewって…
RecyclerViewは、しばしばGridViewやListViewなどの、データ一覧を表示するViewと比較されますが、RecyclerViewは少し違います。GridViewやListViewが、データを表示することに特化していると思いますが、RecyclerViewはリストのアイテムを操作する方に寄っているように思います。
notifyDataSetChangedばかり使っていないか
とりあえずadapterに渡しているobjectにaddしたりaddAllしたら、とりあえずnotifyDataSetChangedしてませんか。そもそもnotifyDataSetChangedは、リスト全体を更新するためのメソッド。ページングのためのメソッドではない。他に何かあるの。
RecyclerView.Adapterのnotify系メソッド一覧
ListViewやGridViewなどありますが、今回はRecyclerViewのnotify系メソッドをまとめます。
今後のことも考えて、RecyclerViewを使えるようになるのは大事な気がしたので。
RecyclerView.Adapter | Android Developers
こちらをなんとなく翻訳してみます。
notifyDataSetChanged()
final void notifyDataSetChanged()
データセットが変更されたことを、登録されているすべてのobserverに通知する。
RecyclerViewに表示されているItem全体に更新をかけるようです。Item内でアニメーション(例えばフェードインとか)を使用しているViewがあると、すべてのItemのアニメーションが実行されます。
notifyItemChanged(int position)
final void notifyItemChanged(int position)
指定したpositionのitemが変更されたことを、登録されているすべてのobserverに通知する。
adapterにindexOf()
とかメソッドを作っておくと、実装しやすくなったりします。
List<MyModel> _objects;
public int indexOf(MyModel object) {
return _objects.indexOf(object);
}
// 初期化済みとする
MyRecyclerViewAdapter _adapter;
// 仮に、Itemが変化したことを通知するコールバックがあったとして……
public void onItemChanged(MyModel object) {
int position = _adapter.indexOf(object);
_adapter.notifyItemChanged(position);
}
OnClickとかのリスナは、結局Adapterにつけるしかないのですかね、なんだか変な感じがしますが……。
notifyItemChanged(int position, Object payload)
final void notifyItemChanged(int position, Object payload)
これはまだ使った経験のないメソッドですが、どうやら……
position
のitemをpayload
で渡したオブジェクトで交換してくれる、というものなのだと思います。
普段は、自分でaddAllみたいなメソッドを実装しなくても、Object渡したら交換できちゃうってことなのだと思います。
payloadで渡したUIオブジェクトの部分を更新できると言うもののようです。
詳しい実装方法は、こちらの記事に書いてありました!↓
RecyclerView の notifyItemChanged をもっと便利に使う
notifyItemInserted(int position)
final void notifyItemInserted(int position)
指定したpositionに新しいitemが挿入されたことを、登録されているすべてのobserverに通知する。
notifyItemMoved(int fromPosition, int toPosition)
final void notifyItemMoved(int fromPosition, int toPosition)
fromPosition
のitemが、toPosition
へ移動したことを、登録されているすべてのobserverに通知する。
notifyItemRangeChanged(int positionStart, int itemCount)
final void notifyItemRangeChanged(int positionStart, int itemCount)
positionStartの位置からitemCountの範囲において、データの変更があったことを登録されているすべてのobserverに通知する。
notifyItemRangeChanged(int positionStart, int itemCount, Object payload)
final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload)
positionStartの位置からitemCountの範囲において、データの変更があったことを登録されているすべてのobserverに通知する。
このメソッドも使ったことないけど、payloadに入れたオブジェクトで更新してもらえるんだと思います。
違うのかな……???
payloadで渡したUIオブジェクトの部分を更新できると言うもののようです。
詳しい実装方法は、こちらの記事に書いてありました!↓
RecyclerView の notifyItemChanged をもっと便利に使う
notifyItemRangeInserted(int positionStart, int itemCount)
final void notifyItemRangeInserted(int positionStart, int itemCount)
positionStartの位置からitemCountの範囲において、データの変更があったことを登録されているすべてのobserverに通知する。
notifyItemRangeRemoved(int positionStart, int itemCount)
final void notifyItemRangeRemoved(int positionStart, int itemCount)
positionStart
を先頭にitemCount
の範囲のitemがデータセットから削除されたことを、登録されているすべてのobserverに通知する。
notifyItemRemoved(int position)
final void notifyItemRemoved(int position)
指定したpositionに存在したitemがデータセットから削除されたことを、登録されたすべてのobserverに通知する。
このメソッドを呼ぶと、消えた行を埋めるようにアニメーションされてかっこいい!
こんな感じで。
みなさんのRecyclerView、RecyclerView.Adapter実装の参考になればと思います。