我使用 hashmap 在我的 Fragment UserFragment 中创建了一个简单的数据,我希望每次单击 Store 按钮单击侦听器时将特定的键值存储在 Room 数据库中,为此我创建了 Room 和 Repository 所需的特定类和 ViewModel 类但是当我尝试从 viewModel 访问所需的数据时出现错误。下面是我的代码
姓名地址.kt
@Entity(tableName = "info")
data class NameAddress(
@PrimaryKey
val id:Int,
@ColumnInfo(name = "name1")
val name1:String,
@ColumnInfo(name = "address")
val address:String
)
道接口 名称地址Dao.kt
@Dao
interface NameAddressDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insertNameAddress(nameAddress: NameAddress)
}
Room 数据库构建器类 AppDatabase.kt
@Database(entities = [NameAddress::class], version = 1)
abstract class AppDatabase:RoomDatabase() {
abstract fun nameAddressDao():NameAddressDao
companion object{
@Volatile
private var INSTANCE:AppDatabase?=null
fun getDatabase(context: Context):AppDatabase{
var tempInstance = INSTANCE
if(tempInstance!=null){
return tempInstance
}
synchronized(this){
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"my_database"
).build()
INSTANCE = instance
return instance
}
}
}
}
名称地址存储库.kt
class NameAddressRepository(private val nameAddressDao: NameAddressDao) {
suspend fun insertNameAddress(nameAddress: NameAddress){
nameAddressDao.insertNameAddress(nameAddress)
}
}
下面是我想在片段中使用的 ViewModel 类。 NameAddressViewModel.kt
class NameAddressViewModel(private val nameAddressRepository: NameAddressRepository):ViewModel() {
fun insertNameAddress(id:Int,name:String, address:String){
val nameAddress = NameAddress(id,name,address)
viewModelScope.launch {
nameAddressRepository.insertNameAddress(nameAddress)
}
}
}
所以最终我按照以下方式在我的片段 UserFragment.kt 中实现了视图模型的实例。
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.ViewModelProvider
import com.example.sharedviewmodeldemo.data.AppDatabase
import com.example.sharedviewmodeldemo.data.NameAddress
import com.example.sharedviewmodeldemo.data.NameAddressViewModel
import com.example.sharedviewmodeldemo.databinding.FragmentUserBinding
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
class UserFragment : Fragment() {
private lateinit var binding: FragmentUserBinding
lateinit var db:AppDatabase
lateinit var nameAddressViewModel: NameAddressViewModel
private var hashMap=HashMap<String, String>()
private val totalPairs=4
private var currentPairIndex=0
private val tag:String = "Room"
private lateinit var currentPair:Map.Entry<String,String>
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
binding = FragmentUserBinding.inflate(layoutInflater,container,false)
hashMap["Robert"] = "NYC"
hashMap["John"] = "Phoenix"
hashMap["Alice"] = "London"
hashMap["Kara"] = "Tennessee"
//retrieve current pair
currentPair = hashMap.entries.elementAt(currentPairIndex)
binding.txtName.text = currentPair.key
binding.txtAddress.text = hashMap.get(currentPair.key)
nameAddressViewModel = ViewModelProvider(this)[NameAddressViewModel::class.java]
binding.btnFlip.setOnClickListener {
// increment currentPairIndex and get the next pair
currentPairIndex++
if (currentPairIndex >= hashMap.size) {
// if we have reached the end of the hashmap, start again from the beginning
currentPairIndex = 0
}
currentPair = hashMap.entries.elementAt(currentPairIndex)
// update the UI with the new pair
binding.txtName.text = currentPair.key
binding.txtAddress.text=hashMap.get(currentPair.key)
}
binding.btnStore.setOnClickListener {
val currentName = currentPair.key
val currentAddress = hashMap.get(currentPair.key)
val nameAddress = currentAddress?.let { it1 -> NameAddress(0,currentName, it1) }
GlobalScope.launch {
db = nameAddressViewModel.insertNameAddress(0,currentName,currentAddress!!) //this line is giving me error
Log.i(tag,"$nameAddress")
}
}
return binding.root
}
}