【问题标题】:Infinite updating of the RecyclerView listRecyclerView 列表无限更新
【发布时间】:2020-01-09 13:59:40
【问题描述】:

在 dagger 和 rxJava 的帮助下,我更新了 RecyclerView 中的列表。一切正常,列表显示。但问题是在日志中我看到这个列表是如何每秒更新的。可能是什么问题呢?在一个类似的项目中,但在 Java 中一切正常,列表在启动时更新一次。 我的网络模块:

@Module(includes = [ViewModelModule::class])
class NetworkModule {

    companion object {
        const val KEY = "key"
        const val BASE_URL = "base_url"
    }

    @Provides
    @Singleton
    fun provideOkHttp(): OkHttpClient {
        val httpClient = OkHttpClient.Builder()
        httpClient.addInterceptor(object : Interceptor {
            @Throws(IOException::class)
            override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
                val original = chain.request()
                val originalHttpUrl = original.url
                val url = originalHttpUrl.newBuilder()
                    //.addQueryParameter("apikey", KEY)
                    .build()
                val requestBuilder = original.newBuilder()
                    .url(url)
                    .header("apikey", KEY)
                val request = requestBuilder.build()
                return chain.proceed(request)
            }
        })
        // logging interceptor
        val logging = HttpLoggingInterceptor()
        logging.level = HttpLoggingInterceptor.Level.BODY
        httpClient.addInterceptor(logging)
        return httpClient.build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(): Retrofit {

        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(provideOkHttp())
            .build()
    }

    @Provides
    @Singleton
    fun provideContactsService(retrofit: Retrofit) : ContactsService{

        return retrofit.create(ContactsService::class.java)
    }
}

我的视图模型:

class ContactsViewModel @Inject constructor(private val contactsRepository: ContactsRepository) :
    ViewModel() {

    var mutableLiveData = MutableLiveData<List<ContactsModel>>()
    private val disposable = CompositeDisposable()

    fun getContactMutableLiveData(): MutableLiveData<List<ContactsModel>> {
        loadData()
        return mutableLiveData
    }

    fun loadData() {

       disposable.add(contactsRepository.modelSingle()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(object : DisposableSingleObserver<List<ContactsModel>>() {
                override fun onSuccess(t: List<ContactsModel>) {
                getContactMutableLiveData().value = t
                }

                override fun onError(e: Throwable) {
                }
            })
        )
    }
}

还有我的活动:

contactsViewModel.getContactMutableLiveData().observe(this@ContactListActivity, Observer {

            mAdapter = ContactsAdapter(this@ContactListActivity, it as ArrayList<ContactsModel>)
            recycler_contacts.layoutManager =
                LinearLayoutManager(applicationContext, OrientationHelper.VERTICAL, false)
            recycler_contacts.adapter = mAdapter
            recycler_contacts.setHasFixedSize(true)

            mAdapter.sortByName()

        })

【问题讨论】:

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


    【解决方案1】:

    好的,如果您只想更新一次数据列表...我建议您查看一个会触发重新加载回收站视图的实时事件 就这样

    //in repo
    private SingleLiveEvent<Boolean> listHasBeenUpdate=new SingleLiveEvent<>();
    //setItsGetterInTheRepo
    public SingleLiveEvent<Boolean> getListHasBeenUpdated(){
    return listHasBeenUpdated();
    }
    //uponSucessfuly fetching your list from retrofit
    listHasBeenUpdated=true;
    //pass list to viewmodel
    

    然后在 ViewModel 中,我会将列表设置为可观察数据,一旦从改造中获取它就会更新(考虑使用 using room db 来存储它)

    //use a setter to set the list from Repo
    ObservableField<List<Contacts>> list=new ObservableField<>();
    
    public SingleLiveEvent<List<Contacts>> fetchContacts(){
       return myRepo.getListHasBeenUpdated();
    }
    

    现在在您的活动课上观察单个现场活动,像这样

    viewModel.fetchContacts().observe(this,contacts->{
      if(contacts){
        //update Recycler
      }
    });
    

    希望对你有所帮助。

    【讨论】:

    • 私人私人 SingleLiveEvent listHasBeenUpdate=new SingleLiveEvent(); ?什么是 SingleListEvent
    • 私有单个实时事件检查列表的更新,它仅在您触发一次时触发,因此,不需要将其设置回 false,因此一旦观察到它就会被观察一次再次对布尔事件进行了更改...
    • 另外,我很抱歉我的回复是用 Java 而不是 Kotlin,但该解决方案可以应用于 Java 和 Kotlin
    【解决方案2】:

    这是一个逻辑错误。你需要重写如下所示的loadData函数

    class ContactsViewModel @Inject constructor(private val contactsRepository: ContactsRepository) :
        ViewModel() {
    
        var mutableLiveData = MutableLiveData<List<ContactsModel>>()
        private val disposable = CompositeDisposable()
    
        fun getContactMutableLiveData(): MutableLiveData<List<ContactsModel>> {
    
            disposable.add(contactsRepository.modelSingle()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(object : DisposableSingleObserver<List<ContactsModel>>() {
                    override fun onSuccess(t: List<ContactsModel>) {
                        mutableLiveData.value = t
                    }
                    override fun onError(e: Throwable) {
                    }
                }))
            return mutableLiveData
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-06
      • 2022-07-28
      • 2017-05-21
      • 1970-01-01
      • 2018-09-06
      • 1970-01-01
      相关资源
      最近更新 更多