RecyclerView отстает только при холодной загрузке, "летая" над предметами - PullRequest
0 голосов
/ 05 июня 2019

Я использую PagingLibrary с RxJava для загрузки данных из Room базы данных. В момент создания базы данных она автоматически добавляет 1000 элементов. Проблема возникает с каждым количеством элементов в базе данных, независимо от того, сколько это - 10 или 1000.

Так в чем же проблема?
После загрузки данных, когда я «пролетаю» над элементами, я вижу, что приложение явно теряет кадры. Это происходит только через первые ~ 50 предметов и после я могу летать, не теряя кадров. Это происходит только после холодного старта, я могу поменять деятельность, добавить новые предметы и нет никаких дополнительных лагов .

Это мой код:
ДАО:

@Query("SELECT * FROM tasks ")
fun getAllAlarms(): DataSource.Factory<Int, TaskEntity>

ViewModel:

override fun getTaskList(): Observable<PagedList<TaskEntity>> {
    val factory = mDao.getAllAlarms()
    val config = PagedList.Config.Builder()
            .setEnablePlaceholders(true)
            .setPageSize(5)
            .setMaxSize(15)
            .build()
    return RxPagedListBuilder(factory, config).buildObservable()
}

Примечание: я играл со значениями PageSize и MaxSize. Я не заметил изменения производительности при игре с этими значениями.

Тогда пришло время для занятия:

private fun getAllTasks() {
    mDisposable.add(
            mViewModel!!.getTaskList
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doAfterNext { mViewModel!!.mProgressBarVisibility.set(View.GONE) }
                    .doOnSubscribe { mViewModel!!.mProgressBarVisibility.set(View.VISIBLE) }
                    .subscribe( mAdapter::submitList)
                    { error -> Log.e("onListReceivedError", error.message, error) })
}

и адаптер :

class TaskPagedAdapter : PagedListAdapter<TaskEntity, TaskViewHolder>(DIFF_CALLBACK) {

private var mLayoutInflater: LayoutInflater? = null
var binding: ItemsAlarmsRecyclerviewBinding? = null

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TaskViewHolder {
    if (mLayoutInflater == null)
        mLayoutInflater = LayoutInflater.from(parent.context)
    binding = DataBindingUtil
            .inflate(mLayoutInflater!!, R.layout.items_alarms_recyclerview,
                    parent, false)
    return TaskViewHolder(binding)
}

override fun onBindViewHolder(holder: TaskViewHolder, position: Int)
    = holder.bindTo(getItem(position))


override fun getItemViewType(position: Int): Int = position


companion object {

    private var DIFF_CALLBACK: DiffUtil.ItemCallback<TaskEntity> = object : DiffUtil.ItemCallback<TaskEntity>() {
        override fun areItemsTheSame(oldItem: TaskEntity, newItem: TaskEntity): Boolean {
            return oldItem === newItem
        }

        @SuppressLint("DiffUtilEquals")
        override fun areContentsTheSame(oldItem: TaskEntity, newItem: TaskEntity): Boolean {
            return oldItem == newItem
        }
    }
}

}

плюс ViewHolder для любопытных:

class TaskViewHolder(private val binding: ItemsAlarmsRecyclerviewBinding?) : RecyclerView.ViewHolder(binding!!.root) {

var entity: TaskEntity? = null

fun bindTo(entity: TaskEntity?) {
    if (entity != null) {
        this.entity = entity;
        binding!!.entity = entity

    }
}

}

Примечание II: я пытался сделать то же самое с LiveData, но это выглядело намного запаздывающим.

Моя "маленькая" идея связана с Observable, так как когда он генерирует данные из базы данных, создает новые наблюдаемые, и каждый раз, когда моя активность наблюдает за новыми наблюдаемыми. Я прав?
В любом случае, у вас есть идеи, как мне решить мою проблему?

...