首页 > 解决方案 > 使用 Retrofit 和 DisposableSingleObserver 获取数据后 notifyDataSetChanged() 不起作用

问题描述

我已经尝试解决这个问题超过 3 个小时。在 Logcat 和 Debug 模式下一切似乎都很好。我正在毫无问题地获取列表,片段正在成功读取 MutableLiveData。只有 notifyDataSetChanged() 函数不起作用,而且它也没有给出任何错误等。如果我手动发送 ArrayList 则它可以工作,但如果它进入 Retrofit 和 DisposableSingleObserver ,那么即使手动列表也不起作用。

我已经尝试了所有可以在互联网上找到的方法。我已经寻找了 20 多种不同的解决方案,但都没有奏效。

API - HoroscopeAPI.kt

interface HoroscopeAPI {
@GET("astraios/horoscopeList.json")
fun getHoroscope(): Single<List<Horoscope>>
}

服务 - HoroscopeAPIService.kt

class HoroscopeAPIService {
private val BASE_URL = "https://wiuma.co"
private val api = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build()
    .create(HoroscopeAPI::class.java)

fun getData(): Single<List<Horoscope>> {
    return api.getHoroscope()
}
}

ViewModel - HoroscopeViewModel.kt

class HoroscopeViewModel : ViewModel() {
private val horoscopeApiService = HoroscopeAPIService()
private val disposable = CompositeDisposable()
val horoscopeList = MutableLiveData<List<Horoscope>>()

fun getDataFromAPI() {
    loadingStatus.value = true
    disposable.add(
        horoscopeApiService.getData()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object : DisposableSingleObserver<List<Horoscope>>() {
                override fun onSuccess(t: List<Horoscope>) {
                    horoscopeList.value = t
                }
                override fun onError(e: Throwable) {
                    e.printStackTrace()
                }
            })
    )
}
}

片段-Horoscope.kt

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    horoscopeViewModel =
        ViewModelProvider(this).get(HoroscopeViewModel::class.java)
    val root = inflater.inflate(R.layout.fragment_horoscope, container, false)
    horoscopeViewModel.getDataFromAPI()
    horoscopeRecyclerView = root.findViewById(R.id.horoscopeRecyclerView)
    horoscopeRecyclerView.layoutManager = LinearLayoutManager(context)
    horoscopeRecyclerView.adapter = recyclerViewAdapter
    observeData()
    return root
}

fun observeData() {
    horoscopeViewModel.horoscopeList.observe(viewLifecycleOwner, Observer { horoscope ->
        horoscope?.let {
            recyclerViewAdapter.updateList(horoscope)
        }
    })}

**适配器 - HoroscopeRecyclerAdapter.kt **

class HoroscopeRecyclerAdapter(val horoscopeList: ArrayList<Horoscope>) :
RecyclerView.Adapter<HoroscopeRecyclerAdapter.HoroscopeViewHolder>() {
class HoroscopeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HoroscopeViewHolder {
    val inflater = LayoutInflater.from(parent.context)
    val view = inflater.inflate(R.layout.horoscope_recycler_row, parent, false)
    return HoroscopeViewHolder(view)
}

@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: HoroscopeViewHolder, position: Int) {
    holder.itemView.horoscopeName.text = horoscopeList.get(position).nameHoroscope
    holder.itemView.horoscopeDates.text =
        horoscopeList.get(position).startDate + " " + horoscopeList.get(position).endDate
    //TODO Gorsel baglantisi eklenecek.

    holder.itemView.setOnClickListener {
        val action =
            HoroscopeFragmentDirections.actionNavigationHoroscopeToNavigationHoroscopeDetails(0)
        Navigation.findNavController(it).navigate(action)
    }
}

override fun getItemCount(): Int {
    return horoscopeList.size
}

fun updateList(newHoroscopeList: List<Horoscope>) {
    horoscopeList.clear()
    horoscopeList.addAll(newHoroscopeList)
    notifyDataSetChanged()
}}

标签: androidkotlinandroid-recyclerviewretrofitnotifydatasetchanged

解决方案


我从 Github 运行了你的项目。notifyDataSetChanged()似乎工作正常。列表项未显示的原因是 RecyclerView 的可见性设置为 GONE。结果到达时需要将其设置回 VISIBLE:

    fun observeData() {
        horoscopeViewModel.horoscopeList.observe(viewLifecycleOwner, Observer { horoscope ->
            horoscope?.let {
                errorText.visibility = View.GONE
                progressBar.visibility = View.GONE
                horoscopeRecyclerView.visibility = View.VISIBLE
                recyclerViewAdapter.updateList(it)
            }
        })

推荐阅读