Android Kotlin Room 与Flow的应用 demo 添加数据并展示
Posted 安果移不动
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Kotlin Room 与Flow的应用 demo 添加数据并展示相关的知识,希望对你有一定的参考价值。
demo 添加数据并展示
依赖
implementation "androidx.activity:activity-ktx:1.5.1"
implementation "androidx.fragment:fragment-ktx:1.5.2"
implementation "androidx.room:room-runtime:2.4.3"
implementation "androidx.room:room-ktx:2.4.3"
package com.example.android_flow_practice.db
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class User(
@PrimaryKey val id: Int,
@ColumnInfo(name = "first_name") val firstName: String,
@ColumnInfo(name = "last_name") val lastName: String
)
package com.example.android_flow_practice.db
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao
interface UserDao
//两条冲突就会替换
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(user: User)
@Query("SELECT * FROM user")
fun getAll(): Flow<List<User>>
package com.example.android_flow_practice.db
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDataBase : RoomDatabase()
abstract fun userDao(): UserDao
companion object
private var instance:AppDataBase? = null
fun getInstance(context: Context): AppDataBase
return instance ?: synchronized(this)
Room.databaseBuilder(context, AppDataBase::class.java,"user.db").build()
.also instance = it
数据库相关的准备好了
那么布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".fragment.UserFragment">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="@+id/et_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="用户id" />
<EditText
android:id="@+id/et_first_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="姓" />
<EditText
android:id="@+id/et_last_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="名" />
</LinearLayout>
<Button
android:id="@+id/bt_add_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="添加用户" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
再那么。对应的fragment
package com.example.android_flow_practice.fragment
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView.LayoutManager
import com.example.android_flow_practice.R
import com.example.android_flow_practice.adapter.UserAdapter
import com.example.android_flow_practice.databinding.FragmentDownloadBinding
import com.example.android_flow_practice.databinding.FragmentUserBinding
import com.example.android_flow_practice.viewmodel.UserViewModel
import kotlinx.coroutines.flow.collect
class UserFragment : Fragment()
private val viewModel: UserViewModel by viewModels()
private val mBinding: FragmentUserBinding by lazy
FragmentUserBinding.inflate(layoutInflater)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View?
// Inflate the layout for this fragment
return mBinding.root
private val TAG = "UserFragment"
override fun onActivityCreated(savedInstanceState: Bundle?)
super.onActivityCreated(savedInstanceState)
context?.let
mBinding.rv.layoutManager = LinearLayoutManager(it)
mBinding.btAddUser.setOnClickListener
val uid = mBinding.etId.text.trim().toString();
val firstName = mBinding.etFirstName.text.trim().toString();
val lastName = mBinding.etLastName.text.trim().toString();
if (TextUtils.isEmpty(firstName) || TextUtils.isEmpty(
lastName
)
)
Toast.makeText(requireContext(), "数据不能为空", Toast.LENGTH_SHORT).show()
return@setOnClickListener
viewModel.insert(
uid = uid.toInt(), firstName = firstName, lastName = lastName
)
context?.let
lifecycleScope.launchWhenCreated
viewModel.getAll().collect value ->
Log.e(TAG, "onActivityCreated: value$value")
val adapter = UserAdapter(it)
mBinding.rv.adapter = adapter
adapter.setData(value)
里面用到了adapter。
package com.example.android_flow_practice.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.android_flow_practice.databinding.ItemUserBinding
import com.example.android_flow_practice.db.User
class UserAdapter(private val context: Context) : RecyclerView.Adapter<BindingViewHolder>()
private val data = ArrayList<User>()
fun setData(data: List<User>)
this.data.clear()
this.data.addAll(data);
notifyDataSetChanged()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BindingViewHolder
val binding = ItemUserBinding.inflate(LayoutInflater.from(context), parent, false)
return BindingViewHolder(binding = binding)
override fun getItemCount(): Int
return data.size
override fun onBindViewHolder(holder: BindingViewHolder, position: Int)
val item = data[position]
val binding = holder.binding as ItemUserBinding
binding.text.text = "$item.id, $item.firstName $item.lastName"
适配器又用到了viewHolder
package com.example.android_flow_practice.adapter
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
class BindingViewHolder(val binding: ViewBinding) : RecyclerView.ViewHolder(binding.root)
再继续
rv用到的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:paddingVertical="4dp"
android:textSize="26sp" />
</LinearLayout>
那么adapter的代码就完成了
最后数据封装在viewModel当中
package com.example.android_flow_practice.viewmodel
import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.example.android_flow_practice.db.AppDataBase
import com.example.android_flow_practice.db.User
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import javax.security.auth.login.LoginException
class UserViewModel(app: Application) : AndroidViewModel(app)
private val TAG = "UserViewModel"
fun insert(uid: Int, firstName: String, lastName: String)
viewModelScope.launch
AppDataBase.getInstance(getApplication()).userDao()
.insert(User(uid, firstName, lastName))
Log.e(TAG, "insert user :$uid")
fun getAll(): Flow<List<User>>
return AppDataBase.getInstance(getApplication()).userDao().getAll()
.catch e -> e.printStackTrace() .flowOn(Dispatchers.IO)
至此 就完成了。
自动查询数据并且将数据设置上去。。核心代码就这些
提供数据提供的也是Flow<List<User>>类型
以上是关于Android Kotlin Room 与Flow的应用 demo 添加数据并展示的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | 在 Android 中使用 Flow 异步流下载文件 )
Kotlin 协程Flow 异步流 ② ( 使用 Flow 异步流持续获取不同返回值 | Flow 异步流获取返回值方式与其它方式对比 | 在 Android 中使用 Flow 异步流下载文件 )