[英]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.