はじめに
今回は、前回の続きをやって聞きたいと思います。前回はRecyclerView
を使ってダミーのデータをリスト表示することができました。今回はEditText
で入力したデータをリスト表示できるようします。
目標
環境
- Android Studio 3.6.3
- Kotlin 1.3.72
作成手順
Gradle
dependencies {
// 省略
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
実装
レイアウトの作成
activity_main.xmlにEditTextとButtonを配置します。
<?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
を使用します。
class MainViewModel : ViewModel() {
val todo = MutableLiveData<String>()
fun addItem(item: String) {
todo.value = item
}
}
MainActivityの定義
ボタンが押された時にEditTextの値をMainViewModel
の変数todo
に代入します。その値の変化を監視してAdapter
にItem
をセットする。
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()
を書かないと最新の状態に反映されないので注意。
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
を使ってデータベースに値を保存する方法について書きます!