How to get soon-to-be-selected page while settling snapping feature on RecyclerView and ViewPager

前端 未结 1 670
灰色年华
灰色年华 2021-01-23 15:33

Background

ViewPager snaps to a view after you perform some scrolling, and so can RecyclerView, if you use something like this:



        
1条回答
  •  孤城傲影
    2021-01-23 16:14

    Seems that for ViewPager, I could use the onPageSelected callback to get which item it's about to settle on.

    So here's the solution for ViewPager (using the library I used) :

        val inflater = LayoutInflater.from(this)
        val viewPagerHolders = HashMap()
        viewPager.adapter = object : RecyclerPagerAdapter() {
    
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewPagerViewHolder {
                return ViewPagerViewHolder(inflater.inflate(R.layout.cell, parent, false))
            }
    
            override fun getItemCount(): Int = 100
    
            override fun onBindViewHolder(holder: ViewPagerViewHolder, position: Int) {
                holder.textView.text = position.toString()
                viewPagerHolders.remove(holder.adapterPosition)
                holder.adapterPosition = position
                viewPagerHolders[position] = holder
    
            }
        }
        viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
            var selectedHolder: ViewPagerViewHolder? = null
    
            override fun onPageScrollStateChanged(state: Int) {}
            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
    
            override fun onPageSelected(position: Int) {
                val holder = viewPagerHolders[position]
                if (holder != null) {
                    if (selectedHolder != null && selectedHolder != holder)
                        selectedHolder!!.textView.text = selectedHolder!!.adapterPosition.toString()
                    holder.textView.text = "selected:${position.toString()}"
                    selectedHolder = holder
                }
            }
        })
    

    And a ViewHolder class that just remembers which adapter position is associated with it (because this is missing for some reason) :

    class ViewPagerViewHolder(itemView: View) : RecyclerPagerAdapter.ViewHolder(itemView) {
        val textView: TextView = itemView.findViewById(android.R.id.text1)
        var adapterPosition: Int = Int.MIN_VALUE
    }
    

    Since it works so well, I decided I will use it, even without blocking touch events functionality.

    Still could be nice to know how to do it for RecyclerView.

    EDIT: for RecyclerView, this can be done: https://stackoverflow.com/a/47580753/878126

    0 讨论(0)
提交回复
热议问题