我正在片段中实现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
}
}
如上所述,我认为.oberserve
中getPostList()
中的PostListFragment
函数没有被调用,因为我尝试了记录但什么也没得到,所以没有数据传递到RecyclerView中。谁能帮我找到不被调用的原因,或者为什么不从ViewModel获取数据的原因?
答案 0 :(得分:0)
我认为这与您的问题无关,但是您的代码有潜在的问题。
observe
部分移至onActivityCreated
会更好,以确保创建了视图。Observer
,而先前的视图仍然存在,因为您的Observer
是匿名的。因此,您必须管理观察者以防止它发生。答案 1 :(得分:0)
我刚刚发现我忘记在RxJava onNext()
中捕获异常,以防出现moshi序列化错误。得到之后,我遇到了一些moshi转换错误。
如果有人不小心忘记抓住moshi错误,请张贴它。
谢谢!