LoginSignup
4
6

More than 3 years have passed since last update.

RecyclerViewとLiveDataを使ってリスト表示

Last updated at Posted at 2020-05-25

はじめに

今回は、前回の続きをやって聞きたいと思います。前回はRecyclerViewを使ってダミーのデータをリスト表示することができました。今回はEditTextで入力したデータをリスト表示できるようします。

目標

環境

  • Android Studio 3.6.3
  • Kotlin 1.3.72

作成手順

Gradle

build.gradle
dependencies {
    // 省略
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.recyclerview:recyclerview:1.1.0'

実装

レイアウトの作成

activity_main.xmlにEditTextとButtonを配置します。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    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"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/submit_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="45dp"
        android:autofillHints="@string/input"
        android:hint="@string/input"
        android:imeOptions="actionSend"
        android:inputType="text"
        app:layout_constraintBottom_toTopOf="@id/main_recycler_view"
        app:layout_constraintEnd_toStartOf="@+id/button"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/main_recycler_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scrollbars="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/submit_text" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="4dp"
        android:text="@string/button"
        app:layout_constraintBottom_toTopOf="@+id/main_recycler_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/submit_text" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainViewModelの作成

EditTextから受け取ったデータをRecyclerViewに反映させるためにLiveDataを使用する。LiveDataはデータの更新を監視します。今回はLiveDataを使用しなくても直接Adapterに値をセットしてあげれば反映できるが、今後データベースの値を非同期で反映させるためにはLiveDataを使用します。

MainViewModel.kt
class MainViewModel : ViewModel() {
    val todo = MutableLiveData<String>()

    fun addItem(item: String) {
        todo.value = item
    }
}

MainActivityの定義

ボタンが押された時にEditTextの値をMainViewModelの変数todoに代入します。その値の変化を監視してAdapterItemをセットする。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    private val mainViewModel = MainViewModel()
    lateinit var adapter: RecyclerAdapter

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

        adapter = RecyclerAdapter()
        main_recycler_view.layoutManager = LinearLayoutManager(this)
        main_recycler_view.adapter = adapter
        main_recycler_view.setHasFixedSize(true)

        add_item_button.setOnClickListener {
            mainViewModel.addItem(submit_text.text.toString())
        }

        mainViewModel.todo.observe(this, Observer {
            adapter.setItem(it)
        })

    }
}

Adapterの定義

MainActivityから呼び出されたsetItem(item: String)によってAdapterに値をセットします。notifyDataSetChanged()を書かないと最新の状態に反映されないので注意。

RecyclerAdapter.kt
class RecyclerAdapter : RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>(){

    private val todoList = mutableListOf<String>()

    fun setItem(item: String) {
        todoList.add(item)
        notifyDataSetChanged()
    }

    class RecyclerViewHolder(val view: View): RecyclerView.ViewHolder(view) {
        val sampleImg = view.sampleImg
        val sampleTxt = view.sampleTxt
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val item = layoutInflater.inflate(R.layout.recyclerview_item, parent, false)
        return RecyclerViewHolder(item)
    }

    override fun getItemCount(): Int = todoList.size

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
        holder.view.let{
            it.sampleImg.setImageResource(R.mipmap.ic_launcher_round)
            it.sampleTxt.text = todoList[position]
        }
    }
}

まとめ

今回はEditTextの値をRecyclerViewに反映させましたが、このままだとアプリを終了した時にデータが残らないのでRoomを使ってデータベースに値を保存するなどしなければならない。
次回はRoomを使ってデータベースに値を保存する方法について書きます!

4
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6