Android
Kotlin
RecyclerView

RecyclerViewの使い方の一例(Kotlin)

この記事は?

androidのRecyclerViewを使おうとして「公式を見てもよくわからん」という自分のような初学者のため、使い方の一例を示します。
自分が参考にしたのは以下二つのサイトですが、コードを写経してもそのままでは動かなかったので所々異なっています。
- Getting Started With RecyclerView in Android — Kotlin
- Create a List with RecyclerView

※なおSQLiteとのデータ連携については書いていません。

コード

以下自分のコードを乗せていきます。
"diary"という単語が出てくるのは、自分が日記アプリを作ってるからです。

build.gradle(Module: app)

追記したのは下のdependencies の一行だけです。

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.example.myapp.todidlist"
        minSdkVersion 23
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support.constraint:constraint-layout:1.1.0'
    implementation 'com.android.support:support-v4:27.1.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support:design:27.1.1'

    implementation "android.arch.persistence.room:runtime:1.0.0"
    kapt "android.arch.persistence.room:compiler:1.0.0"

    // ↓追加した部分
    implementation 'com.android.support:recyclerview-v7:26.1.0'
}
kotlin {
    experimental {
        coroutines "enable"
    }
}

XML

RecyclerViewの外側部分

Toolbarのlayout_heightの"?attr/actionBarSize"は自分の環境では赤字になっていますが、動きます。
一番外側のレイアウトをandroid.support.constraint.ConstraintLayoutにした場合「ToolbarとRecyclerViewが重なって、一番上の要素が隠れる」という現象が発生したのでLinearLayoutに変えてあります。

activity_main_stack.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/main_stack_page_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"

        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:titleTextColor="@color/colorToolbarBottun" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/diary_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="vertical"
        app:layout_constraintTop_toBottomOf="@+id/main_stack_page_toolbar" />
</LinearLayout>

AdapterがRecyclerViewにStackしていく一要素を表すXML

diary_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<!--このTextViewがRecyclerViewの一要素として表示される-->
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textSize="20sp"
    android:padding="20dp"/>

.ktファイル

Activity

diary_recycler_viewはactivity_main_stack.xmlのRecyclerViewのidです。

MainStackActivity.kt
package com.example.myapp.todidlist

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main_stack.*

class MainStackActivity : AppCompatActivity() {
    var diaryTextList: ArrayList<String> = ArrayList()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main_stack)

        addDiary()

        diary_recycler_view.layoutManager = LinearLayoutManager(this)

        diary_recycler_view.adapter = DiaryAdapter(diaryTextList)

    }

    fun addDiary() {
        diaryTextList.add("diary1")
        diaryTextList.add("diary2")
        diaryTextList.add("diary3")
        diaryTextList.add("diary4")
        diaryTextList.add("diary5")
        diaryTextList.add("diary6")
        diaryTextList.add("diary7")
        diaryTextList.add("diary8")
        diaryTextList.add("diary10")
        diaryTextList.add("diary11")
        diaryTextList.add("diary12")
        diaryTextList.add("diary13")
    }
}

Adapter

DiaryAdapter.kt
package com.example.myapp.todidlist

import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView

class DiaryAdapter(private val myDataset: ArrayList<String>) :
        RecyclerView.Adapter<DiaryAdapter.ViewHolder>() {

    // RecyclerViewの一要素となるXML要素の型を引数に指定する
    // この場合はdiary_list_item.xmlのTextView
    class ViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DiaryAdapter.ViewHolder {
        val textView = LayoutInflater.from(parent.context)
                .inflate(R.layout.diary_list_item, parent, false) as TextView
        return ViewHolder(textView)
    }

    // 第1引数のViewHolderはこのファイルの上のほうで作成した`class ViewHolder`です。
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = myDataset[position]
    }

    override fun getItemCount() = myDataset.size
}

実行結果

環境

  • kotlin version 1.2.31 (JRE 1.8.0_152-release-1024-b02)
  • android studio 3.1.2