如何解决没有 livedata 的 Android Studio Room 数据
我得到了以下 Room 数据库,想在 textview 中输出随机用户的名称。不幸的是,运行代码会产生输出: kotlin.unit 在 textview 中。我的文件看起来像这样:
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var mNameviewmodel: Nameviewmodel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mNameviewmodel = viewmodelProvider(this).get(Nameviewmodel::class.java)
val btn = findViewById<Button>(R.id.btn_addName)
val tv = findViewById<TextView>(R.id.tv_showName)
btn.setonClickListener {
val text = findViewById<EditText>(R.id.et_enterName)?.text.toString()
val name = Name(0,text)
// Add Data to Database
mNameviewmodel.addName(name)
Toast.makeText(applicationContext,"Successfully added $text.",Toast.LENGTH_LONG).show()
val randomName = mNameviewmodel.getRandomName()
// Without .toString() I get an error,with it it displays kotlin.unit
tv.text = randomName.toString()
}
}
}
activity_main.xml
<?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">
<TextView
android:id="@+id/tv_showName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.133" />
<EditText
android:id="@+id/et_enterName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:hint="Name"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.244" />
<Button
android:id="@+id/btn_addName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.379" />
</androidx.constraintlayout.widget.ConstraintLayout>
名称.kt
@Entity(tableName = "name_data")
data class Name (
@PrimaryKey(autoGenerate = true) val id: Int,@ColumnInfo(name = "name") val name: String
)
NameDao.kt
@Dao
interface NameDao {
@Insert
fun addName(name: Name)
@Query("SELECT name FROM name_data ORDER BY RANDOM() LIMIT 1")
fun getRandomName(): String
}
NameDatabase.kt
@Database(entities = [Name::class],version = 1,exportSchema = false)
abstract class NameDatabase: RoomDatabase() {
abstract fun nameDao(): NameDao
companion object{
@Volatile
private var INSTANCE: NameDatabase? = null
fun getDatabase(context: Context): NameDatabase{
val tempInstance = INSTANCE
if(tempInstance != null){
return tempInstance
}
synchronized(this){
val instance = databaseBuilder(
context.applicationContext,NameDatabase::class.java,"name_data"
).build()
INSTANCE = instance
return instance
}
}
}
}
NameRepository.kt
class NameRepository(private val nameDao: NameDao) {
fun getRandomName() { nameDao.getRandomName() }
fun addName(name: Name) { nameDao.addName(name) }
}
Nameviewmodel.kt
class Nameviewmodel(application: Application): Androidviewmodel(application) {
private val repository: NameRepository
init {
val nameDao = NameDatabase.getDatabase(application).nameDao()
repository = NameRepository(nameDao)
}
fun addName(name: Name) {
viewmodelScope.launch(dispatchers.IO){
repository.addName(name)
}
}
fun getRandomName() {
viewmodelScope.launch(dispatchers.IO){
repository.getRandomName()
}
}
}
这是按下按钮时textview的输出方式。
尽管数据库已填充。
感谢任何帮助显示数据。谢谢!
解决方法
问题在于,在 viewmodel 中的 getRandomNumber
方法中,您没有返回任何内容,这就是您得到 kotlin.unit
的原因。你应该确保返回一个值
可能的解决方案如下。
- 在您的 dao 中创建一个方法,该方法接受一个数字并返回该行(这基本上是随机名称)
- 从您的 repo 中使用随机数调用该方法,您可以使用
Random.getNextInt
不确定如何获得随机数 - 从您的视图模型调用该方法
- 从你的按钮 onClick 调用 viewModel 方法
确保在适用的情况下使用 suspend
以获得结果。对于我上面展示的情况,将在视图级别启动协程并进行其余调用 (vm,repo,dao) suspend
所以经过一些测试和来回这就是我所拥有的,它似乎正在工作。 如果有人要带一些东西,我很乐意接受它们,并非常感谢 georkost 提供所有有用的提示!
// No changes made to database
@Entity(tableName = "name_data")
data class Name (
@PrimaryKey(autoGenerate = true) val id: Int,@ColumnInfo(name = "name") val name: String
)
//*********************************************************************************
// Changed return type from Query to LiveData<String> (was just String before)
@Dao
interface NameDao {
@Insert
fun addName(name: Name)
@Query("SELECT name FROM name_data ORDER BY RANDOM() LIMIT 1")
fun getRandomName(): LiveData<String> // HERE
}
//*********************************************************************************
// Changed getRandomMeal from fun to val
class NameRepository(private val nameDao: NameDao) {
val getRandomMeal: LiveData<String> = nameDao.getRandomName() // HERE
fun addName(name: Name) { nameDao.addName(name) }
}
//*********************************************************************************
// Added getRandomName val,initialized it and removed the fun
class NameViewModel(application: Application): AndroidViewModel(application) {
val getRandomName: LiveData<String> // HERE
private val repository: NameRepository
init {
val nameDao = NameDatabase.getDatabase(application).nameDao()
repository = NameRepository(nameDao)
getRandomName = repository.getRandomMeal // HERE
}
fun addName(name: Name) {
viewModelScope.launch(Dispatchers.IO){
repository.addName(name)
}
}
}
//*********************************************************************************
// Changed the last row to observe the LiveData and display it in the Text View
class MainActivity : AppCompatActivity() {
private lateinit var mNameViewModel: NameViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mNameViewModel = ViewModelProvider(this).get(NameViewModel::class.java)
val btn = findViewById<Button>(R.id.btn_addName)
val tv = findViewById<TextView>(R.id.tv_showName)
btn.setOnClickListener {
val text = findViewById<EditText>(R.id.et_enterName)?.text.toString()
val name = Name(0,text)
// Add Data to Database
mNameViewModel.addName(name)
Toast.makeText(applicationContext,"Successfully added $text.",Toast.LENGTH_LONG).show()
// HERE
mNameViewModel.getRandomName.observe(this,Observer { String -> tv.text = String })
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。