Recylerview MVVM中未显示JSON数据

时间:2019-10-24 20:46:10

标签: android kotlin data-binding retrofit2 dagger-2

我正在尝试使用数据绑定在Recyclerview中解析Json。当我运行该应用程序时,它仅显示空白屏幕,没有错误/崩溃。

Json数据:

{    “味精”:[       “足球”,       “蟋蟀”,       “棒球”,       “橄榄球”,       “海湾” ],    “状态”:“成功” }

Api

customer    item 1  item 2  item 3
John        Apples  Oranges Bananas
Blake                       Bananas
Steph               Oranges Bananas

adaperclass:

interface SportsApi {
    /**
     * Get the Sports from the API
     */
    @GET("/sports")
    fun getSports(): Observable<Sports>
}

和PostViewModel类:

class PostListAdapter: RecyclerView.Adapter<PostListAdapter.ViewHolder>() {
    private lateinit var postList:Sports

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostListAdapter.ViewHolder {
        val binding: ItemPostBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_post, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: PostListAdapter.ViewHolder, position: Int) {
        holder.bind(postList)
    }

    override fun getItemCount(): Int {

        return if(::postList.isInitialized) postList.msg.size else 0

    }

    fun updatePostList(postList: Sports){
        this.postList = postList
        notifyDataSetChanged()
    }

    class ViewHolder(private val binding: ItemPostBinding):RecyclerView.ViewHolder(binding.postTitle){
        private val viewModel = PostViewModel()

        fun bind(post: Sports){
            viewModel.bind(post)
            binding.viewModel = viewModel
        }
    }
}

有人可以让我知道我在哪里做错了或如何解决吗?如果您需要更多详细信息,请告诉我。

编辑:item_post.xml

class PostViewModel:BaseViewModel() {
    private val postTitle = MutableLiveData<String>()

    fun bind(sports: Sports){
        postTitle.value = sports.msg.toString()
    }

    fun getPostTitle():MutableLiveData<String>{
        return postTitle
    }

}

PostListViewModel类:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="viewModel"
            type="com.gk007.example.ui.post.PostViewModel" />
    </data>

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="16dp"
        android:paddingRight="16dp">

        <TextView
            android:id="@+id/post_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            app:mutableText="@{viewModel.getPostTitle()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
</layout>

1 个答案:

答案 0 :(得分:1)

尝试使用此adapterholder。从支架上取下ViewModel。不应传递完整的Sports对象,而应仅传递列表。

class PostListAdapter: RecyclerView.Adapter<PostListAdapter.ViewHolder>() {
    private lateinit var sports: List<String>

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostListAdapter.ViewHolder {
        val binding: ItemPostBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.item_post, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: PostListAdapter.ViewHolder, position: Int) {
        holder.bind(sports[position])
    }

    override fun getItemCount(): Int {

        return if(::sports.isInitialized) sports.size else 0

    }

    fun updateSports(sports: List<String>){
        this.sports = sports
        notifyDataSetChanged()
    }

    class ViewHolder(private val binding: ItemPostBinding):RecyclerView.ViewHolder(binding.root){
        fun bind(sport: String){
            binding.postTitle.text = sport
        }
    }
}

然后仅通过 msg ,列出以 updateSports

还要从xml中删除 ViewModel

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="16dp"
        android:paddingRight="16dp">

        <TextView
            android:id="@+id/post_title"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
</layout>

更新的ViewModel:

class PostListViewModel:BaseViewModel(){
    @Inject
    lateinit var postApi: PostApi
    val postListAdapter: PostListAdapter = PostListAdapter()

    val loadingVisibility: MutableLiveData<Int> = MutableLiveData()
    val errorMessage:MutableLiveData<Int> = MutableLiveData()
    val errorClickListener = View.OnClickListener { loadPosts() }

    private lateinit var subscription: Disposable

    init{
        loadPosts()
    }

    override fun onCleared() {
        super.onCleared()
        subscription.dispose()
    }

    private fun loadPosts(){
        subscription = postApi.getPosts()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnSubscribe { onRetrievePostListStart() }
            .doOnTerminate { onRetrievePostListFinish() }
            .subscribe(
                { result -> onRetrievePostListSuccess(result.msg) },
                { onRetrievePostListError() }
            )
    }

    private fun onRetrievePostListStart(){
        loadingVisibility.value = View.VISIBLE
        errorMessage.value = null
    }

    private fun onRetrievePostListFinish(){
        loadingVisibility.value = View.GONE
    }

    private fun onRetrievePostListSuccess(postList: List<String>){
        postListAdapter.updateSports(postList)
    }

    private fun onRetrievePostListError(){
        errorMessage.value = R.string.post_error
    }
}