绑定变量为空.如何让 UI 中的观察者等到查询的实时数据从数据库中被挖掘出来?



我正在尝试从数据库中获取数据,然后将其片段绑定到XML。 所以我有存储库将数据从数据库获取到 ViewModel,UI 片段正在观察结果,然后将数据绑定到 XML。 但问题是,即使我在观察器中取消了空数据,该应用程序也说数据为空

。我已经尝试在后台线程上执行查询,它似乎在返回数据时工作正常(照片(。

我认为问题是查询需要时间,而片段中的观察者没有等到查询完成。 所以查询没问题,我完全遵循谷歌样本,但无法找出问题所在。 提前谢谢。

_PhotoRepository

class PhotoRepository @Inject constructor(
private val photoDao: PhotoDoa
) {
fun loadPhotoById(photoId: Int): LiveData<Photo> {
//        var photo: Photo? = null 
//        this is working and i am getting the photo object
//        appExecutors.diskIO().execute { 
photo = photoDao.getObjectPhotoById(photoId)
} 
return photoDao.getPhotoById(photoId)
}
}

_PhotoViewModel

class PhotoViewModel @Inject constructor(private val photoRepository: 
PhotoRepository) :
ViewModel() {
private var _photoId = MutableLiveData<Int>()
val photoId: LiveData<Int>
get() = _photoId

val photo: LiveData<Photo> = Transformations
.switchMap(_photoId) { id ->
photoRepository.loadPhotoById(id)
}

fun setId(photoId: Int) {
//        if (_photoId.value == photoId){
//            return
//        }
_photoId.value = photoId
}
}

_PhotoFragment

class PhotoFragment : Fragment(), Injectable {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
var binding by autoCleared<FragmentPhotoBinding>()
lateinit var photoViewModel: PhotoViewModel
var photo = Photo()

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate<FragmentPhotoBinding>(
inflater,
R.layout.fragment_photo,
container,
false
)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val params = PhotoFragmentArgs.fromBundle(arguments!!)
photoViewModel = ViewModelProviders.of(
this,
viewModelFactory).get(PhotoViewModel::class.java)
photoViewModel.setId(params.photoId)
// photoViewModel.photo.removeObservers(viewLifecycleOwner)
photoViewModel.photo.observe(viewLifecycleOwner, Observer {
if (it != null) {
binding.photo = it
}
})
}
}

_ Doa 类中的查询

@Query(" SELECT * FROM Photo WHERE id = :id")
abstract fun getPhotoById ( id: Int): LiveData<Photo>

_ fragment_photo.xml

<layout
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">
<data>
<import type="com.mustafa.pixabayapp.models.Photo"/>
<variable
name="photo"
type="Photo"/>
<import type="com.mustafa.pixabayapp.utils.StringUtils" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/photo_fragment_image_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:imageUrl="@{photo.webFormatURL}"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/colorTransparentDark"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/photo_fragment_tags"
style="@style/PixabayImageTextUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{StringUtils.getTags(photo.tags)}"
tools:text="TEST - TEST - TEST"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/photo_fragment_user_name"
style="@style/PixabayImageTextUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:text="@{StringUtils.byUser(photo.userName)}"
tools:text="By: Mustafa"/>
<TextView
android:id="@+id/photo_fragment_comments"
style="@style/PixabayImageTextUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_marginEnd="4dp"
android:drawableStart="@drawable/ic_comment"
android:text="@{StringUtils.getCommentsAsString(photo.commentsCount)}"
tools:text="2222"/>
<TextView
android:id="@+id/photo_fragment_favorites"
style="@style/PixabayImageTextUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_toStartOf="@id/photo_fragment_comments"
android:drawableStart="@drawable/ic_favorite"

android:text="@{StringUtils.getFavoritesAsString(photo.favoritesCount)}"
tools:text="2222"/>
<TextView
android:id="@+id/photo_fragment_likes"
style="@style/PixabayImageTextUser"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="4dp"
android:layout_toStartOf="@id/photo_fragment_favorites"
android:drawableStart="@drawable/ic_like"
android:text="@{StringUtils.getLikesAsString(photo.likesCount)}"
tools:text="2222"/>
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
</layout>

_The错误消息:

java.lang.IllegalArgumentException:
Parameter specified as non-null is null: 
method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter 
userName at com.mustafa.pixabayapp.utils.StringUtils.byUser(Unknown 
Source:2)at com.mustafa.pixabayapp.databinding.FragmentPhotoBindingImpl.
executeBindings(FragmentPhotoBindingImpl.java:138)

是的,您对"这需要时间"的假设是正确的。布局希望在绑定后立即绘制一些内容,此时尚未加载photo。 您可以在StringUtils.byUser()中处理 null 值或在布局中添加 null 检查,如下所示: 数据绑定:如果属性不为 null,则设置属性

最新更新