【问题标题】:notifyDataSetChanged() is not working after fetching data with Retrofit and DisposableSingleObserver使用 Retrofit 和 DisposableSingleObserver 获取数据后 notifyDataSetChanged() 不起作用
【发布时间】:2021-05-03 21:11:29
【问题描述】:

我已经尝试解决这个问题超过 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()
}}

【问题讨论】:

    标签: android kotlin android-recyclerview retrofit notifydatasetchanged


    【解决方案1】:

    我从 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)
                }
            })
    

    【讨论】:

    • 天哪!我白白浪费了4个小时的生命。我认为我不可能那么愚蠢,但我是 :D 当涉及到 notifyDataSetChanged 它停止时,我已经逐步遵循调试模式。我以为它有什么问题。但是不,我只是愚蠢,它不会继续前进,因为就像你所说的那样,在获取数据时 RecyclerView 被设置为 GONE 。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    相关资源
    最近更新 更多