[Android]DataBindingを利用したRecyclerViewのセットアップ例
DataBindingを利用してRecyclerViewのセットアップやアダプターの実装をスッキリさせてみました。
リスト表示させるアイテムのレイアウトを用意
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="Item" type="sample.Item"/> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorAccent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:text="@{Item.getTitle()}" android:textAppearance="@style/TextAppearance.AppCompat.Title"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{Item.getMessage()}" android:textAppearance="@style/TextAppearance.AppCompat.Body1"/> </LinearLayout> </layout>
アダプターを実装
ViewHolderには生成した専用のBindingクラスを渡すようにしています。 onBindViewHolderでsetしてviewへの反映が行われます。
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.BindingViewHolder> { private List<Item> mList; public CustomAdapter(List<Item> list) { mList = list; } @Override public BindingViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { ListItemBinding itemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.list_item, parent, false); return new BindingViewHolder(itemBinding); } @Override public void onBindViewHolder(BindingViewHolder holder, int position) { holder.mItemBinding.setItem(mList.get(position)); } @Override public int getItemCount() { return mList.size(); } public static class BindingViewHolder extends RecyclerView.ViewHolder { private ListItemBinding mItemBinding; public BindingViewHolder(ListItemBinding dataBinding) { super(dataBinding.getRoot()); mItemBinding = dataBinding; } } }
BindingAdapterでRecyclerViewのdividerを用意
XMLでItemDecorationをセットできるようにAdapterクラスを作成します。 BindingAdapterを利用してXMLからカスタム属性にリソース等を渡せるようにします。
public class RecyclerViewBindingAdapter { @BindingAdapter("divider") public static void setDividerDrawable(RecyclerView recyclerView, Drawable drawable) { // 適当なItemDecorationを用意 recyclerView.addItemDecoration(new DividerItemDecoration(drawable)); } }
こちらは以下の記事を参考にさせて頂きました。
RecyclerViewのdividerをDataBindingで設定する
RecyclerViewをセットアップ
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/toolbar"/> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" style="@style/RecyclerView.Linear" android:layout_width="match_parent" android:layout_height="match_parent" app:dividerDrawable="@{@drawable/divider}"/> </LinearLayout> </layout>
レイアウトが動的に変わったりしないのであれば、LayoutManagerもstyleに定義しておき、XMLで指定します。
<resources> <style name="RecyclerView"> <item name="android:clipToPadding">false</item> <item name="android:clipChildren">false</item> <item name="android:scrollbarStyle">outsideOverlay</item> </style> <style name="RecyclerView.Linear"> <item name="android:orientation">vertical</item> <item name="layoutManager">android.support.v7.widget.LinearLayoutManager</item> </style> <style name="RecyclerView.Grid"> <item name="layoutManager">android.support.v7.widget.GridLayoutManager</item> </style> </resources>
LayoutManagerやItemDecorationをここまでで設定できたので、コード側がすこしシンプルになりました
public class MainActivity extends AppCompatActivity { private List<Item> mData = new ArrayList<>(); @BindView(R.id.recycler) RecyclerView mRecyclerView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); addList(); CustomAdapter adapter = new CustomAdapter(mData); mRecyclerView.setAdapter(adapter); } private void addList() { // データを追加 } }
まとめ
DataBindingを利用することで動的なViewの変化も半自動的に行えたりするので、まかせられる所は積極的に使っていけそうです。