RecyclerViewの実装

# なぜRecyclerViewが必要になったか
ListViewを設定していたViewにCoordinatorLayoutを適用する必要性があった為、
ListViewをRecyclerViewに移行しました。
CoordinatorLayoutとの連携はまた別の機会に。

ヘッダ、フッタ、セクション版追加しました。
[RecyclerViewのヘッダ、フッタ、セクション](http://qiita.com/ijichi_y/items/0c1a463057f618e3eff3 "RecyclerViewのヘッダ、フッタ、セクション")

RecyclerViewとCoordinatorLayoutとの連携、追加しました。
[RecyclerViewとCoordinatorLayout](http://qiita.com/ijichi_y/items/8160a15e9b1d020542f1 "RecyclerViewとCoordinatorLayout")


# 実装

## gradle
```build.gradle(app)
dependencies {
    - 省略 -
    compile 'com.android.support:recyclerview-v7:26.0.1'
}
```

## Activity
シンプルなAcitivity

```activity_main.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="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>
```

今回は１１件のテストデータを作成して配置

```MainActivity.kt
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のアダプタ

```RecyclerAdapter.kt
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
レイアウトを操作するクラス

```RecyclerItemViewHolder.kt
class RecyclerItemViewHolder(private val view: RecyclerItemView) : RecyclerView.ViewHolder(view) {
  fun update(state: RecyclerState){
    view.update(state)
  }
}
```

##Custom View
セル１つ１つのレイアウトです
無くてもViewHolderでxmlを直接設定して操作することも可能だが、作ったほうが便利

```recycler_item_view.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>
```

```RecyclerItemView.kt
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
  }
}
```

# できあがり
![screen.png](https://qiita-image-store.s3.amazonaws.com/0/199764/114ac244-41d1-9e05-ac20-429c4622da79.png)

# 注意点
```RecyclerAdapter.kt
    recycler.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
```
これがないと何も表示されなくて小パニックになります。

代わりにxmlへlayoutManagerを追加して対応することも可能

```activity_main.xml
<?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は自前で実装する必要あり。