Android RxJava Retrofit MVVM RecyclerView不显示

时间:2019-02-17 23:28:48

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

我正在片段中实现RecyclerView。 XML应该是正确的,因为我尝试使用硬编码数据,并且API调用确实根据控制台中的Log从服务器返回了正确的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的片段。我认为.oberserve中的getPostList()函数没有被调用,因为我尝试记录它但什么也没得到。

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

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

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

我刚刚发现我忘记在RxJava onNext()中捕获异常,以防出现moshi序列化错误。得到之后,我遇到了一些moshi转换错误。 如果有人不小心忘记抓住moshi错误,请张贴它。 谢谢!