[英]Circular horizontal Recycler View Adapter
我有一个水平的回收视图适配器,我试图让它在两个方向上都是圆形的。 我为此找到了多种解决方案,但在 Kotlin 中没有找到。 我的适配器的 getItemCount 和 onBindViewHolder 看起来像这样。
override fun onbindViewHolder(holder: ViewHolder<T>, position: Int){
val Data = items[position]
holder.bind(Data, position, viewHoldBindFunc)
override fun getItemCount(): Int = items.size
我尝试将这两个功能更改为以下内容,但 Integer.MAX_VALUE 使整个屏幕崩溃。
override fun getItemCount(): Int {return Integer.MAX_VALUE}
and
override fun onbindViewHolder(holder: ViewHolder<T>, position: Int){
val NewPosition = position % items.size
val Data = items[NewPosition]
holder.bind(Data, NewPosition, viewHoldBindFunc)
谢谢
这是 Kotlin 中的一个似乎有效的解决方案。 我基于https://gist.github.com/nesquena/d09dc68ff07e845cc622中的一些代码。
事实证明,如果您调用回收器适配器的 notifyItemRemoved() 和 notifyItemInserted() 方法(对于您看不到的视图),它不会移动您当前正在查看的视图的 position,但它会改变RecyclerView 感知到的是您的右侧和左侧。
我得到了这个工作,所以我不妨分享结果:这个回收器适配器假装你显示的同一组项目有 5 个副本,并且每当显示左侧或右侧最远副本之一的项目时,它使用adapter.notifyItemRemoved() 和 notifyItemInserted() 将 RecyclerView 的感知转移到正在滚动的一侧。
您可能需要对此进行一些测试。 滚动几秒钟似乎对我来说效果很好。 为了安全起见,我总共放了 5 个副本(1 个在中间,两个在周围),但我敢打赌,如果你稍微弄乱了它,这将适用于 3 个副本。 :)
package com.github.ajsnarr98.testingplayground
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.github.ajsnarr98.testingplayground.databinding.ActivityCircularBinding
class CircularActivity : AppCompatActivity() {
private val list = listOf<Int>(1,2,3,4,5,6,7,8,9,10,11,12)
lateinit var binding: ActivityCircularBinding
lateinit var recyclerAdapter: CircularAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityCircularBinding.inflate(layoutInflater)
setContentView(binding.root)
recyclerAdapter = CircularAdapter(list, binding.list)
binding.list.apply {
adapter = recyclerAdapter
layoutManager = LinearLayoutManager(this@CircularActivity, RecyclerView.HORIZONTAL, false)
}
recyclerAdapter.init()
}
}
package com.github.ajsnarr98.testingplayground
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class CircularAdapter(
private val items: List<Int>,
private val recyclerView: RecyclerView,
) : RecyclerView.Adapter<CircularAdapter.ViewHolder>() {
var offset: Int = 0
var numSets = 5
val initialPosition = items.size * 2 // two sets of items before, two sets after
fun init() {
recyclerView.scrollToPosition(initialPosition)
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.'
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
// this example only supports LinearLayoutManager
val layoutManager: LinearLayoutManager = recyclerView.layoutManager as? LinearLayoutManager ?: return
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
if (isInBoundarySet(firstVisibleItemPosition)) {
insertItemsLeft()
}
if (isInBoundarySet(lastVisibleItemPosition)) {
insertItemsRight()
}
}
})
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_number, parent, false)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(itemForPosition(position))
}
override fun getItemCount(): Int = items.size * numSets
/**
* Returns true if the given position is within items.size from 0 or
* getItemCount().
*/
private fun isInBoundarySet(position: Int): Boolean {
return position + items.size >= itemCount || position - items.size < 0
}
private fun itemForPosition(position: Int) = items[position % items.size]
/**
* Pretends a new set of items was inserted to the right, and a set was was removed to the left.
*/
fun insertItemsRight() {
numSets--
notifyItemRangeRemoved(0, items.size)
numSets++
notifyItemRangeInserted(itemCount, items.size)
}
/**
* Pretends a new set of items was inserted to the left, and a set was was removed to the right.
*/
fun insertItemsLeft() {
numSets--
notifyItemRangeRemoved(itemCount-items.size, items.size)
numSets++
notifyItemRangeInserted(0, items.size)
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bind(item: Int) {
if (this.itemView is TextView) {
this.itemView.text = item.toString()
}
}
}
companion object {
private const val NUMBER_VIEW = 0
}
}
item_number.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/frame"
android:textAlignment="center"
android:textStyle="bold"
android:textSize="40sp"
tools:text="1"/>
activity_circular.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CircularActivity">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Circular recycler view"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/list"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
框架.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<!-- View background color -->
<solid
android:color="@color/white" >
</solid>
<!-- View border color and width -->
<stroke
android:width="3dp"
android:color="@color/black" >
</stroke>
</shape>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.