# なぜRecyclerViewが必要になったか
ListViewを設定していたViewにCoordinatorLayoutを適用する必要性があった為、
ListViewをRecyclerViewに移行しました。
CoordinatorLayoutとの連携はまた別の機会に。
ヘッダ、フッタ、セクション版追加しました。
RecyclerViewのヘッダ、フッタ、セクション
RecyclerViewとCoordinatorLayoutとの連携、追加しました。
RecyclerViewとCoordinatorLayout
実装
gradle
dependencies {
- 省略 -
compile 'com.android.support:recyclerview-v7:26.0.1'
}
## Activity
シンプルなAcitivity
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/mainRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</FrameLayout>
今回は11件のテストデータを作成して配置
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val states = arrayListOf<RecyclerState>()
for(i in 0..10){
val state = RecyclerState()
state.text = "$i 件目"
states.add(state)
}
val adapter = RecyclerAdapter(this, states)
val recycler = findViewById<RecyclerView>(R.id.mainRecycler)
recycler.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
recycler.adapter = adapter
}
}
##Adapter
RecyclerViewのアダプタ
class RecyclerAdapter(
private val context: Context,
private val states: List<RecyclerState>) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = RecyclerItemView(context)
return RecyclerItemViewHolder(view)
}
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
if(viewHolder is RecyclerItemViewHolder){
viewHolder.update(states[position])
}
}
override fun getItemCount(): Int {
return states.count()
}
}
##ViewHolder
レイアウトを操作するクラス
class RecyclerItemViewHolder(private val view: RecyclerItemView) : RecyclerView.ViewHolder(view) {
fun update(state: RecyclerState){
view.update(state)
}
}
##Custom View
セル1つ1つのレイアウトです
無くてもViewHolderでxmlを直接設定して操作することも可能だが、作ったほうが便利
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/recyclerItemText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="20sp"
android:scrollbars="vertical"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:background="@android:color/darker_gray"/>
</FrameLayout>
class RecyclerItemView constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : FrameLayout(context, attrs, defStyleAttr){
private val textView: TextView
init {
val rootView = LayoutInflater.from(context).inflate(R.layout.recycler_item_view, this)
textView = rootView.findViewById(R.id.recyclerItemText)
setOnClickListener {
// クリック処理
}
}
fun update(state: RecyclerState){
textView.text = state.text
}
}
できあがり
注意点
recycler.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
これがないと何も表示されなくて小パニックになります。
代わりにxmlへlayoutManagerを追加して対応することも可能
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/mainRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
app:layoutManager="android.support.v7.widget.LinearLayoutManager"/>
</FrameLayout>
まとめ
ListViewはシンプルで良かった感じた。
特にheader、footer、セクションを自動でやってくれない点は不便で、
RecyclerViewは自前で実装する必要あり。