Android Jetpack

ROOM + Coroutine Flow - 7 (Room + Flow + ListAdapter CRUD)

----___<<<<< 2023. 1. 29. 00:37

 

buildscript {

    ext {
        room_version = '2.5.0'
    }

}
id 'kotlin-kapt'
// ROOM
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"

// coroutine
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1"

 

 

 

class MainActivity : AppCompatActivity() {
private lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val db = MyDatabase.getDatabase(this)
val recyclerView = binding.userRV
val myListAdapter = MyListAdapter()
recyclerView.adapter = myListAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
binding.create.setOnClickListener {
val name = binding.name.text.toString()
val age = binding.age.text.toString()
CoroutineScope(Dispatchers.IO).launch {
val userEntity = UserEntity(0, name, age.toInt())
db.userDao().insert(userEntity)
}
}
binding.read.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch {
db.userDao().getAllDataFlow().collect {
withContext(Dispatchers.Main) {
myListAdapter.submitList(it)
}
}
}
}
binding.next.setOnClickListener {
val intent = Intent(this, NextActivity::class.java)
startActivity(intent)
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub
class MyListAdapter : ListAdapter<UserEntity, MyListAdapter.MyListAdapterViewHolder>(DiffCallback){
companion object {
private val DiffCallback = object : DiffUtil.ItemCallback<UserEntity>() {
override fun areItemsTheSame(oldItem: UserEntity, newItem: UserEntity): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: UserEntity, newItem: UserEntity): Boolean {
return oldItem == newItem
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyListAdapterViewHolder {
val viewHolder = MyListAdapterViewHolder(UserItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
return viewHolder
}
override fun onBindViewHolder(holder: MyListAdapterViewHolder, position: Int) {
holder.bind(getItem(position))
}
class MyListAdapterViewHolder(private var binding : UserItemBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(userEntity: UserEntity) {
binding.id.text = userEntity.id.toString()
binding.name.text = userEntity.name
binding.age.text = userEntity.age.toString()
}
}
}
class NextActivity : AppCompatActivity() {
private lateinit var binding : ActivityNextBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNextBinding.inflate(layoutInflater)
setContentView(binding.root)
val db = MyDatabase.getDatabase(this)
val recyclerView = binding.userRV
val myListAdapter = MyListAdapter()
recyclerView.adapter = myListAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
binding.read.setOnClickListener {
CoroutineScope(Dispatchers.IO).launch {
db.userDao().getAllDataFlow().collect {
withContext(Dispatchers.Main) {
myListAdapter.submitList(it)
}
}
}
}
binding.update.setOnClickListener {
val id = binding.id.text.toString().toInt()
CoroutineScope(Dispatchers.IO).launch {
val result = db.userDao().getAllData()
val userEntity = result[id]
userEntity.name = "updated"
db.userDao().update(userEntity)
}
}
binding.remove.setOnClickListener {
val id = binding.id.text.toString().toInt()
CoroutineScope(Dispatchers.IO).launch {
val result = db.userDao().getAllData()
val userEntity = result[id]
db.userDao().delete(userEntity)
}
}
}
}
view raw NextActivity.kt hosted with ❤ by GitHub
@Database(entities = [UserEntity::class], version = 2)
abstract class MyDatabase : RoomDatabase() {
abstract fun userDao() : UserDao
companion object {
@Volatile
private var INSTANCE : MyDatabase? = null
fun getDatabase(
context : Context
) : MyDatabase {
return INSTANCE ?:synchronized(this){
val instance = Room.databaseBuilder(
context.applicationContext,
MyDatabase::class.java,
"user_database"
)
.fallbackToDestructiveMigration()
.build()
INSTANCE = instance
instance
}
}
}
}
view raw MyDatabase.kt hosted with ❤ by GitHub
@Entity(tableName = "user_table")
data class UserEntity (
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id")
var id : Int = 0,
@ColumnInfo(name = "name")
var name : String,
@ColumnInfo(name = "age")
val age : Int
)
view raw UserEntity.kt hosted with ❤ by GitHub
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(user : UserEntity)
@Query("SELECT * FROM user_table")
fun getAllData() : List<UserEntity>
@Query("SELECT * FROM user_table")
fun getAllDataFlow() : Flow<List<UserEntity>>
@Update
fun update(userEntity: UserEntity)
@Delete
fun delete(userEntity: UserEntity)
}
view raw UserDao.kt hosted with ❤ by GitHub
<?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"
tools:context=".MainActivity"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_margin="10dp">
<EditText
android:id="@+id/name"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="name"/>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_margin="10dp">
<EditText
android:id="@+id/age"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="age"/>
</androidx.cardview.widget.CardView>
<Button
android:id="@+id/create"
android:text="create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
<Button
android:id="@+id/read"
android:text="read"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
<Button
android:id="@+id/next"
android:text="next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/userRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<?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"
tools:context=".NextActivity"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_margin="10dp">
<EditText
android:id="@+id/id"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="id"/>
</androidx.cardview.widget.CardView>
<Button
android:id="@+id/read"
android:text="read"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
<Button
android:id="@+id/update"
android:text="update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
<Button
android:id="@+id/remove"
android:text="remove"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/userRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/id"
android:text="id"
android:layout_margin="20dp"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/name"
android:text="name"
android:layout_marginLeft="70dp"
android:layout_marginTop="20dp"
android:textSize="30dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/age"
android:text="age"
android:textSize="30dp"
android:layout_marginTop="20dp"
android:layout_marginLeft="200dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
view raw user_item.xml hosted with ❤ by GitHub