Данные JSON не отображаются в Recylerview MVVM - PullRequest
1 голос
/ 24 октября 2019

Я пытаюсь проанализировать Json в Recyclerview, используя привязку данных. Когда я запускаю приложение, оно показывает только пустой экран без ошибок / сбоев.

Данные Json:

{"msg": ["football", "cricket", "baseball", "rugby "," gulf "]," status ":" success "}

API

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

Класс adaper:

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
        }
    }
}

и класс PostViewModel:

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

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

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

}

Может кто-нибудь, пожалуйста, дайте мне знать, где я делаю неправильно или как ее решить? Если вам нужна дополнительная информация, пожалуйста, дайте мне знать.

Редактировать: item_post.xml

<?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>

Класс PostListViewModel:

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) },
                { 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.updatePostList(postList)
    }

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

1 Ответ

1 голос
/ 25 октября 2019

Попробуйте с этим adapter и holder. Снимите ViewModel с держателя. Вместо передачи полного Sports объекта вы должны передать только List.

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 , List в updateSports

Итакже удалите ViewModel из xml

<?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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...