代码之家  ›  专栏  ›  技术社区  ›  liminal

使用分页体系结构组件调试分页

  •  1
  • liminal  · 技术社区  · 6 年前

    因此,我使用 LiveData 和房间数据库,但我没有看到它实际上分页。也许我没有正确调试以确认分页正在发生。任何建议都将不胜感激。

    @Query("SELECT * FROM notes ORDER BY id ASC")
    fun allNotes(): DataSource.Factory<Int, NoteEntity>
    

    然后在我的 NotesRepository ,我从 NoteEntity Note 将我的数据层实现细节和应用程序的其余部分分开(我是干净体系结构的粉丝)。所以结果是 DataSource.Factory<Int, Note>

    override fun allNotes(): DataSource.Factory<Int, Note> =
            notesDao.allNotes().map { mapper.fromDb(it) }
    

    在我的 ViewModel 哪里 PAGE_SIZE

    val noteList: LiveData<PagedList<Note>> =
            LivePagedListBuilder(
                    getNotesUseCase.allNotes(), PAGE_SIZE)
    

    我的 简单来说就是:

    data class Note(
        val id: Long = 0,
        val text: String
    )
    

    然后我将在中显示注释 RecyclerView .

    我的 ViewHolder

    class NoteViewHolder(parent: ViewGroup) : RecyclerView.ViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.note_item, parent, false))  {
       private val idView = itemView.findViewById<TextView>(R.id.noteId)
       private val nameView = itemView.findViewById<TextView>(R.id.noteText)
       private var note: Note? = null
    
       /**
        * Items might be null if they are not paged in yet. PagedListAdapter will re-bind the
        * ViewHolder when Item is loaded.
        */
        fun bindTo(note: Note?) {
            this.note = note
            idView.text = note?.let { it.id.toString() } ?: ""
            nameView.text = note?.text ?: ""
        }
    }
    

    我的 Adapter 包含:

    class NoteAdapter(
        private val clickListener: ClickListener) : PagedListAdapter<Note, NoteViewHolder>(diffCallback) {
    
    override fun onBindViewHolder(holder: NoteViewHolder, position: Int) {
        Timber.d("Binding view holder at position $position")
        val note = getItem(position)
    
        with(holder) {
            bindTo(note)
            note?.let {
                itemView.setOnClickListener {
                clickListener(note)
            }
        }
    }
    
    }
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder =
            NoteViewHolder(parent)
    
    companion object {
        /**
         * This diff callback informs the PagedListAdapter how to compute list differences when new
         * PagedLists arrive.
         */
        private val diffCallback = object : DiffUtil.ItemCallback<Note>() {
            override fun areItemsTheSame(oldItem: Note, newItem: Note): Boolean =
                    oldItem.id == newItem.id
    
            override fun areContentsTheSame(oldItem: Note, newItem: Note): Boolean =
                    oldItem == newItem
            }
        }
    }
    

    还有我的 Fragment

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
    
        setupRecyclerView()
    
        viewModel = ViewModelProviders.of(this, noteListViewModelFactory).get(NoteListViewModel::class.java)
        viewModel.noteList.observe(this, Observer { pagedNoteList ->
            pagedNoteList?.let { render(pagedNoteList) }
        })
    }
    
    private fun render(pagedNoteList: PagedList<Note>) {
        recyclerViewAdapter.submitList(pagedNoteList)
    }
    

    RecyclerView中的数据已成功加载,并且我在绑定每个项时都会看到调试日志。 我的理解是 PagedListAdapter PagedList

    我的数据源包含100个项目,因此我希望页面大小为20时,在平均大小的手机上进行测试时,会有5个数据调用。

    如何调试以确保正确的调用数?另外,在上面的实现中,默认情况下是否使用其中一个(PositionalDataSource、ItemKeyedDataSource或PageKeyedDataSource)?

    1 回复  |  直到 6 年前
        1
  •  1
  •   liminal    6 年前

    回答我自己的问题:

    PositionalDataSource 默认情况下正在使用。

    NoteAdapter.onBindViewHolder() :

    Log.d("NoteAdapter", currentList)
    

    哪里 currentList PagedListAdapter .

    /**
     * Returns the PagedList currently being displayed by the Adapter.
     * etc.
     */
    @Nullable
    public PagedList<T> getCurrentList() {
        return mDiffer.getCurrentList();
    }
    

    当用户滚动时,新项目被绑定到视图持有者,日志显示 当前列表 正在迭代。

    还要注意,当您将页面大小设置为 N 3 * N 更多的物品将被放入 . 这是因为我在请求页面列表时使用了默认配置:

    val noteList: LiveData<PagedList<Note>> =
            LivePagedListBuilder(
                    getNotesUseCase.allNotes(), PAGE_SIZE)
                    .build()
    

    private val pagedListConfig = PagedList.Config.Builder()
            .setEnablePlaceholders(true)
            .setInitialLoadSizeHint(INITIAL_LOAD_SIZE)
            .setPageSize(PAGE_SIZE)
            .build()
    
    val noteList = LivePagedListBuilder<Int,Note>(getNotesUseCase.allNotes(), pagedListConfig).build()
    

    默认情况下, 初始加载大小提示 等于页面大小*3。