【Android】SimpleRecyclerViewAdapter
めずらしくあんどろいだーーーーーー
ねいてぃぶはらくちんでよいね!!!最高!ねむい!体調悪い!つらい!でも納期も時間も待ってくれない!
はい、RecyclerViewAdapterね。簡単なやつならこうしましょう。
app/build.gradle
抜粋です。databindingも使うのでね。
apply plugin: 'kotlin-kapt' android { dataBinding { enabled = true } } dependencies { ext.android_support_version = "27.1.1" implementation "com.android.support:recyclerview-v7:$android_support_version" }
SimpleRecyclerViewAdapter.kt
おもむろに以下をじっそうしましょう。
package hoge; import android.content.Context import android.support.v7.widget.RecyclerView import android.view.View import android.view.ViewGroup import java.lang.reflect.ParameterizedType abstract class SimpleRecyclerViewAdapter<V : View, I : Any?>(defaultItems: ArrayList<I>? = null) : RecyclerView.Adapter<SimpleRecyclerViewAdapter<V, I>.ItemViewHolder>() { protected val isEmpty get() = !items.any() private val items: ArrayList<I> = arrayListOf() init { defaultItems?.let { items.addAll(it) } } fun removeAll() { items.clear() notifyDataSetChanged() } fun addItem(item: I) { items.add(item) notifyItemInserted(items.count()) } fun removeItem(item: I) { val index = items.indexOf(item) items.removeAt(index) notifyItemRemoved(index) } fun updateItem(position: Int, item: I) { items[position] = item notifyItemChanged(position) } final override fun getItemCount() = items.count() final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(onCreateItemView(parent.context).apply { layoutParams = RecyclerView.LayoutParams( RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT ) }) @Suppress("UNCHECKED_CAST") final override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { (holder.itemView as? V)?.let { onBindItemView(it, items[position], position) } } @Suppress("UNCHECKED_CAST") protected open fun onCreateItemView(context: Context) = ((javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<*>) .constructors.first().newInstance(context) as V protected abstract fun onBindItemView(itemView: V, item: I, position: Int) inner class ItemViewHolder(view: View) : RecyclerView.ViewHolder(view) }
使い方
view_hoge_list_item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/textViewTitle" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
HogeListItemView.kt
package hoge import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater import android.widget.LinearLayout import hoge.R import kotlinx.android.synthetic.main.view_hoge_list_item.view.* internal class HogeListItemView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : LinearLayout(context, attrs, defStyleAttr) { init { LayoutInflater.from(context).inflate(R.layout.view_hoge_list_item, this) } fun setTitle(title: String) { textViewTitel.text = title } }
HogeFragment.kt
省略。Bindingのサンプル書くのめんどい。
HogeFragmentVM.kt
package hoge import android.content.Context import hoge.SimpleRecyclerViewAdapter import hoge.HogeListItemView internal class HogeFragmentVM() { val recyclerViewAdapter = object : SimpleRecyclerViewAdapter<HogeListItemView, String>(arrayListOf<String>("Hogeeeeee", "Aaaaaaaaaaa")) { override fun onBindItemView(itemView: HogeListItemView, item: String, position: Int) { itemView.setTitle(item) } } }
fragment_hoge.xml
抜粋。
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <variable name="vm" type="hoge.HogeFragmentVM" /> </data> <android.support.v7.widget.RecyclerView android:layout_width="match_parent" android:layout_height="match_parent" app:layoutManager="android.support.v7.widget.LinearLayoutManager" app:recyclerViewAdapter="@{vm.recyclerViewAdapter}" /> </layout>
onBindItemViewだけoverrideすればいいから簡単ですね。はい。いじょー