Бесконечное обновление списка RecyclerView - PullRequest
0 голосов
/ 09 января 2020

С помощью dagger и rx Java я обновляю список в 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()

        })

Ответы [ 2 ]

0 голосов
/ 10 января 2020

Это была логическая ошибка. Вам нужно переписать функцию 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
    }

}
0 голосов
/ 09 января 2020

Хорошо, если вы хотите обновить свой список данных только один раз ... Я бы порекомендовал вам посмотреть на одно прямое событие, которое вызовет перезагрузку вашего представления переработчика. Таким образом,

//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, я бы установил список как Наблюдаемые данные, которые будут обновляться после извлечения из модернизации (рассмотрим использование комнаты 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
  }
});

надеюсь, это вам поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...