Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/186.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何在设置RecyclerView和ViewPager上的抓拍功能时快速获得被选中的页面 背景_Android_Android Recyclerview_Android Viewpager_Snapping - Fatal编程技术网

Android 如何在设置RecyclerView和ViewPager上的抓拍功能时快速获得被选中的页面 背景

Android 如何在设置RecyclerView和ViewPager上的抓拍功能时快速获得被选中的页面 背景,android,android-recyclerview,android-viewpager,snapping,Android,Android Recyclerview,Android Viewpager,Snapping,ViewPager在执行一些滚动操作后会捕捉到视图,如果您使用类似以下内容,也可以执行RecyclerView: LinearSnapHelper().attachToRecyclerView(recyclerView) 或者使用库捕捉到某条边,如所示。如图所示,如果您愿意,它几乎可以完全模仿Commonware提到的ViewPager 如果需要,这两个视图可以以相同的方式工作(捕捉到单个视图,可以选择占用整个可用空间),因此这个问题是关于这两个视图的 ViewPager存在一些回收视图的问题

ViewPager
在执行一些滚动操作后会捕捉到视图,如果您使用类似以下内容,也可以执行
RecyclerView

LinearSnapHelper().attachToRecyclerView(recyclerView)
或者使用库捕捉到某条边,如所示。如图所示,如果您愿意,它几乎可以完全模仿Commonware提到的
ViewPager

如果需要,这两个视图可以以相同的方式工作(捕捉到单个视图,可以选择占用整个可用空间),因此这个问题是关于这两个视图的

ViewPager存在一些回收视图的问题,但这些问题可以修复,例如使用

问题 我需要更新新显示的视图的UI,只要RecyclerView/ViewPager在滚动中即将空闲

当然,由于用户仍然可以触摸它,这将是一个知道将要发生什么的问题,因此我还需要在它设置滚动状态时阻止触摸事件

这意味着,例如,当用户从第0页到第1页抛出一个页面时,一旦捕捉开始,触摸事件就会被阻止,我就能够知道它会捕捉到第1页并更新此页面

这里的问题是,RecyclerView和ViewPager都不提供此功能。我只能在它停止滚动后,而不是在它稳定下来时,才能得到所选的项目

我试过的 对于
ViewPager
,适配器只有一个选项,不幸的是,它告诉我在完成设置后选择了。我有一个函数,它可以告诉我在任何给定时间(使用)的滚动位置,但它不能告诉我移动的方向(左/右),我也不知道要选择哪个数据和哪个视图持有者
addOnPageChangeListener
还提供滚动状态(空闲、设置、拖动)

对于
RecyclerView
我可以得到一个滚动状态的回调,它将在何时结算以及何时变为空闲状态,但我看不到如何获得它将结算的项目

关于阻止触摸事件,我想我可以在它稳定下来的时候在上面放一个可点击的视图(没有内容,所以用户看不见),在它空闲的时候隐藏它(将可见性设置为<代码>消失),但我想知道是否有更好的方法

我尝试使用
setOnTouchListener
来查看
RecyclerView
空闲和设置状态,但当我尝试在设置时触摸时,它被卡在了当前的滚动位置

因此,
RecyclerView
ViewPager
都存在着完成这一切的障碍

以下是我目前的工作成果:

浏览页面:

回收视图:

我尝试的POC代码(包括
ViewPager
RecyclerView
):

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val inflater = LayoutInflater.from(this)

        //viewPager area

        viewPager.adapter = object : RecyclerPagerAdapter<RecyclerPagerAdapter.ViewHolder>() {
            var selectedHolder: RecyclerPagerAdapter.ViewHolder? = null
            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
                return object : RecyclerPagerAdapter.ViewHolder(inflater.inflate(R.layout.cell, parent, false)) {}
            }

            override fun getItemCount(): Int = 100

            override fun onBindViewHolder(holder: ViewHolder, position: Int) {
                (holder.itemView as TextView).text = position.toString()
            }

            override fun setPrimaryItem(container: ViewGroup?, position: Int, obj: Any?) {
                super.setPrimaryItem(container, position, obj)
                //TODO get the soon-to-be-selected page sooner
                val holder = obj as RecyclerPagerAdapter.ViewHolder
                if (selectedHolder != null && selectedHolder != holder)
                    (selectedHolder!!.itemView as TextView).text = position.toString()
                (holder.itemView as TextView).text = "selected:${position.toString()}"
                selectedHolder = holder
            }

        }
        viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {
                when (state) {
                    ViewPager.SCROLL_STATE_DRAGGING -> Log.d("AppLog", "onPageScrollStateChanged: SCROLL_STATE_DRAGGING")
                    ViewPager.SCROLL_STATE_IDLE -> Log.d("AppLog", "onPageScrollStateChanged: SCROLL_STATE_IDLE")
                    ViewPager.SCROLL_STATE_SETTLING -> Log.d("AppLog", "onPageScrollStateChanged: SCROLL_STATE_SETTLING")
                }
            }

            override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
                Log.d("AppLog", "onPageScrolled: position:$position positionOffset :$positionOffset positionOffsetPixels:$positionOffsetPixels")
            }

            override fun onPageSelected(position: Int) {
                Log.d("AppLog", "onPageSelected:" + position)
            }
        })

        //recyclerView area

        // Not needed, as I use a library for this: LinearSnapHelper().attachToRecyclerView(recyclerView)
        recyclerView.setHasFixedSize(true)
        recyclerView.adapter = object : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
            override fun getItemCount(): Int = 100

            override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
                return object : RecyclerView.ViewHolder(inflater.inflate(R.layout.cell, parent, false)) {}
            }

            override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
                (holder.itemView as TextView).text = position.toString()
            }
        }
        recyclerView.addOnPageChangedListener { oldPosition, newPosition -> Log.d("AppLog", "OnPageChanged:$oldPosition->$newPosition") }
        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            @SuppressLint("ClickableViewAccessibility")
            override fun onScrollStateChanged(recyclerView: RecyclerView?, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                when (newState) {
                    RecyclerView.SCROLL_STATE_IDLE -> {
                        Log.d("AppLog", "state: SCROLL_STATE_IDLE")
                        recyclerViewStateTextView.text = "state: SCROLL_STATE_IDLE"
                        //setOnTouchListener doesn't really work well. It makes the scrolling stuck
                        //                        recyclerView!!.setOnTouchListener(null)
                    }
                    RecyclerView.SCROLL_STATE_SETTLING -> {
                        //TODO when settling, block touches, and update the soon-to-be-focused page
                        Log.d("AppLog", "state: SCROLL_STATE_SETTLING")
                        recyclerViewStateTextView.text = "state: SCROLL_STATE_SETTLING"
                        //                        recyclerView!!.setOnTouchListener(object : View.OnTouchListener {
                        //                            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                        //                                return true
                        //                            }
                        //
                        //                        })
                    }
                    RecyclerView.SCROLL_STATE_DRAGGING -> {
                        Log.d("AppLog", "state: SCROLL_STATE_DRAGGING")
                        recyclerViewStateTextView.text = "state: SCROLL_STATE_DRAGGING"
                    }
                }
            }
        })
        recyclerViewStateTextView.text = "state: SCROLL_STATE_IDLE"
    }
问题
  • 如何获取ViewPager/RecyclerView正在结算时的回调,包括将要捕捉到的项目

  • 从触摸事件稳定到空闲,我如何阻止触摸事件?有没有比我写的更好的方法(在顶部有一个可点击的视图)


  • 更新:


    似乎对于ViewPager,我可以使用回调来获取它将要处理的项目。想知道以这种方式获取其页面的ViewHolder的最佳方式是什么。我可以将所需数据保存在
    onBindViewHolder
    中,然后自己检查,但我想知道是否有更好的方法


    现在缺少的是如何为
    RecyclerView
    执行此操作,以及如何阻止触摸事件(如果有比我编写的更好的方法的话)。该库有一个名为
    addOnPageChangedListener
    的函数,但它是在结算完成后调用的,因此它在这里没有帮助。

    似乎对于ViewPager,我可以使用onPageSelected回调来获取它将结算的项目

    下面是ViewPager的解决方案(使用我使用的库):

    由于它工作得很好,我决定使用它,即使不阻止触摸事件功能

    知道如何为RecyclerView做这件事还是不错的


    编辑:对于RecyclerView,可以这样做:

    似乎对于ViewPager,我可以使用onPageSelected回调来获取它要处理的项目

    下面是ViewPager的解决方案(使用我使用的库):

    由于它工作得很好,我决定使用它,即使不阻止触摸事件功能

    知道如何为RecyclerView做这件事还是不错的

    编辑:对于RecyclerView,可以执行以下操作:

    <TextView
        xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:id="@android:id/text1"
        android:textSize="36sp" tools:text="@tools:sample/lorem"/>
    
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent" android:orientation="vertical"
        tools:context="com.example.user.snapblockertest.MainActivity">
    
        <TextView
            android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="ViewPager :"/>
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="0px"
            android:layout_weight="1"/>
    
        <TextView
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:text="RecyclerView with snapping:"/>
    
        <com.lsjwzh.widget.recyclerviewpager.RecyclerViewPager
            android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="0px"
            android:layout_weight="1" android:orientation="horizontal"
            app:layoutManager="android.support.v7.widget.LinearLayoutManager" app:rvp_singlePageFling="true"
            app:rvp_triggerOffset="0.1"/>
    
        <TextView
            android:id="@+id/recyclerViewStateTextView" android:layout_width="match_parent" android:layout_height="wrap_content"/>
    
    </LinearLayout>
    
    //https://github.com/henrytao-me/recycler-pager-adapter
    implementation "me.henrytao:recycler-pager-adapter:2.1.0"
    //https://github.com/lsjwzh/RecyclerViewPager
    implementation 'com.github.lsjwzh.RecyclerViewPager:lib:v1.1.2@aar'
    
        val inflater = LayoutInflater.from(this)
        val viewPagerHolders = HashMap<Int, ViewPagerViewHolder>()
        viewPager.adapter = object : RecyclerPagerAdapter<ViewPagerViewHolder>() {
    
            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
                }
            }
        })
    
    class ViewPagerViewHolder(itemView: View) : RecyclerPagerAdapter.ViewHolder(itemView) {
        val textView: TextView = itemView.findViewById(android.R.id.text1)
        var adapterPosition: Int = Int.MIN_VALUE
    }