0
点赞
收藏
分享

微信扫一扫

Android Kotlin Room 与Flow的应用 demo 添加数据并展示


Android Kotlin Room 与Flow的应用 demo 添加数据并展示_android

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"

Android Kotlin Room 与Flow的应用 demo 添加数据并展示_开发语言_02

 

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)


}
}

至此 就完成了。

Android Kotlin Room 与Flow的应用 demo 添加数据并展示_User_03

 

 自动查询数据并且将数据设置上去。。核心代码就这些

提供数据提供的也是Flow<List<User>>类型

Android Kotlin Room 与Flow的应用 demo 添加数据并展示_android_04

 

举报

相关推荐

0 条评论