【问题标题】:Android RxJava Retrofit MVVM RecyclerView does not show upAndroid RxJava Retrofit MVVM RecyclerView 不显示
【发布时间】:2019-07-11 07:53:04
【问题描述】:

我正在片段中实现 RecyclerView。 XML 应该是正确的,因为我使用我的硬编码数据进行了尝试,并且 API 调用确实根据控制台中的日志从服务器返回了正确的 json 数据。问题是 RecyclerView 适配器没有从我的 Observable 获取任何数据。这是我的实现

在 PostDataService 接口中我使用 Retrofit 来获取 Observable>

interface PostDataService {

    @GET(".")
    fun getPosts(
        @Query(value = "offset") offset: Long = 0,
        @Query(value = "limit") limit: Long = 10,
        @Query(value = "subscribedOnly") subscribedOnly: Boolean = false
    ): Observable<List<Post>>

    companion object {
        val retrofit: PostDataService = Retrofit.Builder()
            .baseUrl("http:aws/api/post/")
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(MoshiConverterFactory.create())
            .client(client)
            .build()
            .create(PostDataService::class.java)
    }
}


在 PostListRepository 中,我使用 RxJava 运算符来获取 LiveData

class PostListRepository {

    private val postListLiveData: MutableLiveData<List<Post>> = MutableLiveData()
    private val compositeDisposable: CompositeDisposable = CompositeDisposable()

    fun getPostListLiveData(): MutableLiveData<List<Post>> {
        val postList: MutableList<Post> = ArrayList()
        val retrofitInstance = PostDataService.retrofit
        val postListObservable = retrofitInstance.getPosts()
        compositeDisposable.add(
            postListObservable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .flatMapIterable { it }
                .subscribeWith(object : DisposableObserver<Post>() {
                    override fun onError(e: Throwable) {
                        // if some error happens in our data layer our app will not crash, we will
                        // get error here
                    }

                    override fun onNext(post: Post) {
                        postList.add(post)
                    }

                    override fun onComplete() {
                        postListLiveData.postValue(postList)
                    }
                })
        )
        return postListLiveData
    }

    fun clear() {
        compositeDisposable.clear()
    }
}


在 PostListViewModel 中,我将存储库中的 LiveData 传递到此 ViewModel。

class PostListViewModel : ViewModel() {

    private var postListRepository: PostListRepository = PostListRepository()

    fun getPostList(): MutableLiveData<List<Post>> {
        return postListRepository.getPostListLiveData()
    }

    fun clear() {
        postListRepository.clear()
    }
}


这是包含 RecyclerView 的片段。我认为getPostList() 中的.oberserve 函数没有被调用,因为我尝试记录它但一无所获。

class PostListFragment : Fragment() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var swipeLayout: SwipeRefreshLayout
    private lateinit var postListViewModel: PostListViewModel
    private val postListAdapter = PostRecyclerViewAdapter()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val rootView = inflater.inflate(R.layout.view_post_list, container, false)
        recyclerView = rootView.findViewById(R.id.postRecyclerView)
        recyclerView.apply {
            setHasFixedSize(true)
            addItemDecoration(VerticalSpaceItemDecoration(36))
            layoutManager = LinearLayoutManager(context)
            adapter = postListAdapter
        }

        postListViewModel = ViewModelProviders.of(this).get(PostListViewModel::class.java)
        getPostList()

        swipeLayout = rootView.findViewById(R.id.swipeLayout)
        swipeLayout.setColorSchemeResources(R.color.colorPrimary)
        swipeLayout.setOnRefreshListener {
            getPostList()
            swipeLayout.isRefreshing = false
        }
        return rootView
    }

    override fun onDestroy() {
        super.onDestroy()
        postListViewModel.clear() // to avoid memory leak
    }

    private fun getPostList() {
        postListViewModel.getPostList().observe(this, Observer<List<Post>> { resource ->
            postListAdapter.setPostList(resource)
            postListAdapter.notifyDataSetChanged()
        })
    }
}


这是 RecyclerView 的适配器:

class PostRecyclerViewAdapter : RecyclerView.Adapter<PostViewHolder>() {

    private var postList: List<Post> = ArrayList()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostViewHolder {
        // create a new view
        val postView = PostView(parent.context)
        // set the view's size, margins, paddings and layout parameters
        return PostViewHolder.from(postView)
    }

    override fun getItemCount(): Int = postList.size

    override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
        val curPost = postList[position]
        holder.postView.apply {
            setPostOwnerDisplayName(curPost.content.userDisplayedName)
            setPostOwnerRole(curPost.content.role)
            setPostOwnerAvatar(R.mipmap.ic_launcher_round)
            setPostText(curPost.content.text)
            setPostImage(curPost.content.smallMediaPaths[0])
            setLikeState(curPost.liked)
            setBookmarkState(curPost.bookmarked)
        }
    }

    fun setPostList(postList: List<Post>) {
        this.postList = postList
    }
}

正如我上面提到的,我认为PostListFragment 中的getPostList() 中的.oberserve 函数没有被调用,因为我尝试记录它但什么也没得到,所以没有数据传递到RecyclerView。谁能帮我找出它没有被调用的原因,或者它没有从 ViewModel 获取数据的原因?

【问题讨论】:

    标签: android mvvm android-recyclerview retrofit2 rx-java2


    【解决方案1】:

    我认为这与您的问题无关,但您的代码存在潜在问题。

    1. observe 部分移动到onActivityCreated 会更好地确保创建视图。
    2. 重新创建片段视图时,将添加一个新的Observer,而前一个仍然存在,因为您的Observer 是匿名的。因此,您必须管理观察者以防止它发生。

    【讨论】:

    • 感谢您的回复!我不太明白为什么我需要在父活动中做片段的东西?我想当片段在onDestroy() 中被销毁时,观察会消失,因为那也是我清除视图模型的地方?
    • 首先,onActivityCreated() 是片段生命周期之一!其次,片段onDestroyView() 可以在没有onDestroy() 的情况下调用。在这种情况下,片段实例仍然存在,而视图被销毁。
    【解决方案2】:

    我刚刚发现我忘记在 RxJava onNext() 中捕获异常,以防得到 moshi 序列化错误。得到那个之后,我得到了一些 moshi 转换错误。 发布它以防有人不小心忘记捕捉到 moshi 错误。 谢谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-11
      • 2021-04-01
      • 2018-06-03
      • 2014-10-31
      • 2019-09-25
      • 1970-01-01
      • 2018-06-23
      • 1970-01-01
      相关资源
      最近更新 更多