【发布时间】:2019-05-06 10:53:50
【问题描述】:
我有一个带有一个选项卡的 ViewPager,它通过带有 LiveData 对象的 ViewModel 从 Room 中检索数据。
当我切换到任何选项卡并返回到显示项目列表的选项卡时,一切正常,但是当我从后台返回时,我不知道为什么,但我收到的列表少了。
例如我第一次进入“列表片段”。
我从 5 个不同的实体中检索数据,并显示了 5 个列表项
转到背景并返回“列表片段”
4 个列表有数据,但 1 个为空
转到背景并返回“列表片段”
3 个列表有数据,但 2 个为空
...直到完全为空,但随后我切换选项卡并且列表填满
感谢您的帮助。
视图模型
class TagsViewModel(application: Application) : AndroidViewModel(application) {
private var repository: TagsRepository = TagsRepository(application)
private var listText: LiveData<List<Text>> = repository.getAllText()
private var listUrl: LiveData<List<Url>> = repository.getAllUrl()
private var listEmail: LiveData<List<Email>> = repository.getAllEmail()
private var listPhone: LiveData<List<Phone>> = repository.getAllPhone()
private var listLauncher: LiveData<List<Launcher>> = repository.getAllLauncher()
fun getData(): List<BaseTag>{
var allData= mutableListOf<BaseTag>()
if (listText.value != null){
listText.value!!.forEach {
allData.add(it)
}
}
if (listUrl.value != null){
listUrl.value!!.forEach {
allData.add(it)
}
}
if (listEmail.value != null){
listEmail.value!!.forEach {
allData.add(it)
}
}
if (listPhone.value != null){
listPhone.value!!.forEach {
allData.add(it)
}
}
if (listLauncher.value != null){
listLauncher.value!!.forEach {
allData.add(it)
}
}
return allData
}
//-------TEXT--------
fun insertText(text: Text) {
repository.insertText(text)
}
fun deleteTextByID(id: Int) {
repository.deleteTextByID(id)
}
fun getAllText(): LiveData<List<Text>> {
return listText
}
fun deleteAllText() {
repository.deleteAllText()
}
repository getAllText() 返回 tagsDao.getTextList()
而 Dao 是:
@Query("SELECT * FROM Text")
fun getTextList(): LiveData<List<Text>>
编辑
我将 viewPager 更改为不再重新创建片段,在 onViewCreated 中观察 LiveData,在 onPause 中清除列表并在 onResume 中再次设置数据并添加 viewLyfeCycleOwner
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
v = inflater.inflate(R.layout.fragment_my_tags, container, false)
return v
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupUI()
}
private fun setupUI(){
val recyclerView = v.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(context)
recyclerView.setHasFixedSize(true)
recyclerView.adapter = adapter
tagsViewModel = ViewModelProviders.of(this).get(TagsViewModel::class.java)
getTags()
(activity as MainActivity).mToolbar.onMenuItemClick {
when (it!!.itemId){
R.id.btnDeleteAll -> toast("sort")
R.id.btnOrderBy -> tagsViewModel.deleteAll()
}
}
}
private fun getTags(){
tagsViewModel.getAllText().observe(viewLifecycleOwner,
Observer<List<Text>> { t -> adapter.setTags(t!!) })
tagsViewModel.getAllEmail().observe(viewLifecycleOwner,
Observer<List<Email>> { t -> adapter.setTags(t!!) })
tagsViewModel.getAllUrl().observe(viewLifecycleOwner,
Observer<List<Url>> { t -> adapter.setTags(t!!) })
tagsViewModel.getAllPhone().observe(viewLifecycleOwner,
Observer<List<Phone>> { t -> adapter.setTags(t!!) })
tagsViewModel.getAllLauncher().observe(viewLifecycleOwner,
Observer<List<Launcher>> { t -> adapter.setTags(t!!) })
}
override fun onPause() {
adapter.clear()
super.onPause()
}
override fun onResume() {
adapter.setTags(tagsViewModel.getData())
super.onResume()
}
它的工作方式与以前相同,当我从 onResume 后台返回时,我的 viewModel 总是少返回一个完全随机的列表,有时是 textList,有时是 emailList……为什么它会丢失数据?我不知道为什么。
编辑 2
class TagsAdapter : RecyclerView.Adapter<TagsAdapter.TagHolder>() {
private var baseList: MutableList<BaseTag> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TagHolder {
val itemView = LayoutInflater.from(parent.context)
.inflate(R.layout.tag_item, parent, false)
return TagHolder(itemView)
}
override fun onBindViewHolder(holder: TagHolder, position: Int) {
val tag = baseList[position]
holder.tvAlias.text = tag.content
holder.tvDate.text = tag.date?.let { AppUtils.toDate(it) }
holder.ivType.background = tag.type?.let { getDrawable(it) }
}
override fun getItemCount(): Int {
return baseList.size
}
fun setTags(list: List<BaseTag>) {
if (this.baseList.isEmpty()) {
this.baseList = list as MutableList<BaseTag>
} else {
this.baseList.addAll(list)
}
orderList()
notifyDataSetChanged()
}
private fun getDrawable(type: String): Drawable? {
when (type) {
AppConstants.TYPE_TEXT -> return ContextCompat.getDrawable(App.instance, R.drawable.ic_text)
AppConstants.TYPE_EMAIL -> return ContextCompat.getDrawable(App.instance, R.drawable.ic_write)
AppConstants.TYPE_URL -> return ContextCompat.getDrawable(App.instance, R.drawable.ic_clean)
AppConstants.TYPE_PHONE -> return ContextCompat.getDrawable(App.instance, R.drawable.ic_mobile)
AppConstants.TYPE_LAUNCHER -> return ContextCompat.getDrawable(App.instance, R.drawable.ic_code)
}
return null
}
private fun orderList(){
baseList.sortBy { it.date }
baseList.reverse()
}
fun clear(){
this.baseList.clear()
}
inner class TagHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var tvAlias: TextView = itemView.findViewById(R.id.txtAlias)
var tvDate: TextView = itemView.findViewById(R.id.txtDate)
var ivType: ImageView = itemView.findViewById(R.id.ivType)
}
}
【问题讨论】:
-
您应该在活动中观察
onStart,在片段中观察onViewCreated(使用getViewLifecycleOwner观察片段)。 -
感谢您的评论。我做到了,还是一样,我更新了问题,我不太确定现在是什么问题......
-
这很有趣。您可以分享一个演示项目来复制它吗?
标签: android android-room android-architecture-components android-livedata