在解决我的问题之前,让我告诉您我的应用程序如何工作。
我有一个小食品杂货应用程序,可以通过翻新从api读取数据,然后将其保存到Roomdatabase。
为了更好地进行Ui实验,我需要在主屏幕上实现带有edittext的searchview。
因此,我决定在dao中编写查询代码,并通过标题过滤器获取所有数据。
但是问题在于,当我填写编辑文本并点击按钮获得我过滤的产品时,没有任何反应,也没有搜索。
好吧,我想我的问题可能出在我在存储库和viewmodel中实现的将数据插入roomdatabase的代码中。如果不是,我的代码有什么问题?
如果您看一下我的代码,将不胜感激。
这是我的代码:
这是房间桌子:
@Entity(tableName = "newTable")
data class RoomEntity(
@PrimaryKey
(autoGenerate = true)
val id : Int? ,
@ColumnInfo val title: String,
@ColumnInfo val image: String
)
道:@Dao
interface RoomDaoQuery {
@Query("SELECT * FROM newTable")
fun getAllProduct () : LiveData<List<RoomEntity>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertDataToDatabase(model : List<RoomEntity>)
@Query("SELECT * FROM newTable WHERE title LIKE '%' || :search || '%'")
fun searchByName(search: String): List<RoomEntity>
}
仓库:class Repository(private val database: DatabaseRoom) {
fun getAllProduct() = database.GetDao.getAllProduct()
private fun retrofit(): ApiRetrofit {
return Retrofit.Builder()
.baseUrl("http://192.168.43.106/")
.addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
.build()
.create(ApiRetrofit::class.java)
}
suspend fun fettchAllDat(): List<RoomEntity> {
return retrofit().getProduct()
}
suspend fun insertToDatabase(model : List<RoomEntity>) {
database.GetDao.insertDataToDatabase(fettchAllDat())
}
// this is for local search
fun searchWithName (title : String) : List<RoomEntity> {
return database.GetDao.searchByName(title)
}
}
View 模型:class ViewmodelRoom(application: Application) : AndroidViewModel(application) {
val product = MutableLiveData<List<RoomEntity>>()
private val repository = Repository(DatabaseRoom.getInstance(application))
private var viewModelJob = SupervisorJob()
private val viewModelScope = CoroutineScope(viewModelJob + Dispatchers.Default)
fun getAllProduct() = repository.getAllProduct()
fun setup() {
viewModelScope.launch{
product.postValue(repository.fettchAllDat())
insertall()
}
}
fun insertall() {
viewModelScope.launch {
repository.insertToDatabase(repository.fettchAllDat())
}
}
fun searchByTitle(title : String) = CoroutineScope(Dispatchers.Default).launch{
repository.searchWithName(title)
}
}
和MainActivity:
class MainActivity : AppCompatActivity() {
val viewModel: ViewmodelRoom by lazy {
ViewModelProvider(this).get(ViewmodelRoom::class.java)
}
@RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editText: EditText = findViewById(R.id.edittext)
val search: ImageView = findViewById(R.id.searchview)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)
search.setOnClickListener {
viewModel.searchByTitle(editText.text.toString())
editText.text.clear()
}
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
viewModel.searchByTitle(editText.text.toString())
}
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
if (isNetworkAvaliable(applicationContext)) {
viewModel.setup()
viewModel.product.observe(this, Observer {
recyclerView.apply {
layoutManager = GridLayoutManager(this@MainActivity, 2)
adapter = RecyclerAdapterMain(it, this@MainActivity)
}
})
} else {
viewModel.getAllProduct().observe(this, Observer { list ->
recyclerView.apply {
layoutManager = GridLayoutManager(this@MainActivity, 2)
adapter = RecyclerAdapterMain(list, this@MainActivity)
}
})
}
}
最佳答案
最终我得到了适当的结果。
我将代码放在这里,希望对某人有用。
道:
@Query("SELECT * FROM newTable WHERE title LIKE :name")
fun search (name : String) :LiveData<List<RoomEntity>>
仓库:
fun search(name : String): LiveData<List<RoomEntity>>{
return database.GetDao.search(name)
}
fun search(name : String) : LiveData<List<RoomEntity>> {
return repository.search(name)
}
MainActivity :
val editText: EditText = findViewById(R.id.edittext)
val search: ImageView = findViewById(R.id.searchview)
recyclerView = findViewById(R.id.recyclerview)
search.setOnClickListener {
// this is an extention function that observe data
searchProduct(editText.text.toString())
}
editText.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
searchProduct(editText.text.toString())
}
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
})
private fun searchProduct(title : String) {
var searchText = title
searchText = "%$title%"
viewModel.search(searchText).observe(this@MainActivity , Observer {
d("main" , "$it")
recyclerView.apply {
layoutManager = GridLayoutManager(this@MainActivity, 2)
adapter = RecyclerAdapterMain(it, this@MainActivity)
}
})
}