【发布时间】: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