多个水平回收器视图在垂直回收器视图内同步滚动

问题描述 投票:0回答:1

我有一个垂直的RecyclerView,其中每一行都是一个水平的RecyclerView。 我想做的是,无论你滚动哪个水平 RecyclerView,所有其他的都会一起滚动。

这是我的代码:

垂直回收机视图:

 <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/purchase_ticket_seats_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    tools:listitem="@layout/view_seats_horizontal"
                    android:nestedScrollingEnabled="false"/>

垂直回收器视图内部视图:

    <?xml version="1.0" encoding="utf-8"?>
   <androidx.constraintlayout.widget.ConstraintLayout 
    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:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    >


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/seats_horizontal_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:nestedScrollingEnabled="false"
        android:orientation="horizontal"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:listitem="@layout/view_seat"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/seat_row_name" />


    <TextView
        android:id="@+id/seat_row_name"
        android:layout_width="30dp"
        android:layout_height="match_parent"
        android:text="A"
        android:textSize="18sp"
        android:paddingStart="5dp"
        android:paddingEnd="3dp"
        android:paddingTop="7dp"
        android:textColor="#fff"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

我尝试将垂直 recyclerview 放入水平滚动视图中,并禁用水平 recyclerview 的水平滚动。但没有运气。我还尝试为水平回收器视图提供相同的滚动侦听器。

这是我想要实现的图像。用户可以垂直滚动,如果用户滚动一个水平行,其他行会一起滚动:

android android-recyclerview horizontal-scrolling
1个回答
0
投票

在MainActivity中有recyclerView垂直:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        verticalRecyclerView.layoutManager = LinearLayoutManager(this)

        val onScrollListener = object: RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                (recyclerView.adapter as? Adapter)?.matchOffset()
            }
        }

        verticalRecyclerView.addOnScrollListener(onScrollListener)
        verticalRecyclerView.adapter = Adapter(verticalRecyclerView)
    }
}

在适配器中有列表 recyclerView 水平:

class Adapter(private val parentRV: RecyclerView): RecyclerView.Adapter<CustomViewHolder>() {

    var horizontalRecyclerViews = mutableListOf<RecyclerView>()
    var absoluteOffset: Int? = null
    //numberOfItems
    override fun getItemCount(): Int {
        return 25
    }

    fun matchOffset(offset: Int? = absoluteOffset) {
        offset?.let { offsetValue ->
            horizontalRecyclerViews.forEach { recyclerView ->
                val currentOffset = recyclerView.computeHorizontalScrollOffset()
                if (offsetValue != currentOffset) {
                    recyclerView.scrollBy(offsetValue-currentOffset, 0)
                }
            }
        }
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
        val layoutInflator = LayoutInflater.from(parent.context)
        val cellForRow = layoutInflator.inflate(R.layout.item_recycler_view, parent, false)
        return  CustomViewHolder(cellForRow)
    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        holder.view.horizontalRecyclerView.layoutManager = LinearLayoutManager(holder.view.context, LinearLayoutManager.HORIZONTAL, false)

        val onTouchListener = object: RecyclerView.OnItemTouchListener {
            override fun onTouchEvent(p0: RecyclerView, p1: MotionEvent) {
            }
            override fun onInterceptTouchEvent(p0: RecyclerView, p1: MotionEvent): Boolean {
                if (p1.action == MotionEvent.ACTION_UP) {
                    absoluteOffset = p0.computeHorizontalScrollOffset()
                    return true
                }
                return false
            }
            override fun onRequestDisallowInterceptTouchEvent(p0: Boolean) {
            }
        }

        val onScrollListener = object: RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                val value = recyclerView.computeHorizontalScrollOffset()
                matchOffset(value)
            }
        }


        val child = BlockAdapter()
        holder.view.horizontalRecyclerView.tag = position
        holder.view.horizontalRecyclerView.clearOnScrollListeners()
        holder.view.horizontalRecyclerView.addOnItemTouchListener(onTouchListener)
        holder.view.horizontalRecyclerView.addOnScrollListener(onScrollListener)
        holder.view.horizontalRecyclerView.adapter = child
        horizontalRecyclerViews.add(holder.view.horizontalRecyclerView)
    }
}

class BlockAdapter(): RecyclerView.Adapter<CustomViewHolder>() {

    //numberOfItems
    override fun getItemCount(): Int {
        return 30
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
        val layoutInflator = LayoutInflater.from(parent.context)
        val cellForRow = layoutInflator.inflate(R.layout.item_block, parent, false)
        return  CustomViewHolder(cellForRow)
    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        holder.view.block.setBackgroundColor(
                if (position % 2 == 0) {
                    Color.BLUE
                } else {
                    Color.RED
                }
        )
        holder.view.block.setTextColor(Color.WHITE)
        holder.view.block.text = position.toString()
    }
}

class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {

    init {
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.