嘿,我在Recyclerview中有多個布局。我想改成視圖系結。我有多個布局,在所有的布局中都有相同的ID,唯一不同的是位置不同。所以我怎樣才能為它制作視圖固定器。我想避免多個視圖固定器。我試著不想使用這個多個視圖固定器,有什么可能做到嗎?因為所有的代碼在viewholder中都是一樣的。謝謝
。AdapterClass.kt
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
class AdapterClass(private val horizontal: Boolean = false) : RecyclerView.Adapter<AdapterViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)。AdapterViewHolder {
val inflatedView。View = if (horizontal) {
LayoutInflater.from(parent.context).inflate(R.layout.horizontal_layout, parent, false)
} else {
LayoutInflater.from(parent.context).inflate(R.layout.vertical_layout, parent, false)
}
return AdapterViewHolder(inflatedView)
}
override fun onBindViewHolder( holder: AdapterViewHolder, position: Int) {
holder.bingImage(position)
}
}
.........
AdapterViewHolder.kt
import android.graphics.drawable.Drawable
import android.view.View。
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
class AdapterViewHolder( itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bingImage(position: Int) {
with(itemView) {
val color = if (isSelected) {
itemView.context.resources.getColor(R.color.blue)
} else {
itemView.context.resources.getColor(R.color.green)
}
main_container.setBackgroundColor(color)
}
}
}
Vertical.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"?
android:id="@ id/main_container"/span>
android:layout_width="match_parent"/span>
android:layout_height="match_parent"/span>
android:orientation="垂直">
<ImageView
android:id="@ id/imageView"/span>
android:layout_gravity="center"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content" />
</LinearLayout>
Horizontal.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"?
android:id="@ id/main_container"/span>
android:layout_width="match_parent"/span>
android:layout_height="match_parent"/span>
android:orientation="horizontal">
<ImageView
android:id="@ id/imageView"/span>
android:layout_gravity="center"/span>
android:layout_width="wrap_content"/span>
android:layout_height="wrap_content" />
</LinearLayout>
uj5u.com熱心網友回復:
使用一個ViewHolder沒有合適的方法,最好的解決方案是為每個不同的ViewHolder創建多個ViewHolders,因為這是ViewHolder模式的核心優勢。
然而,如果你堅持使用一個ViewHolder,我想出了一個解決方案,但最后,你將不得不單獨處理每個布局系結。
配接器
span class="hljs-keyword">class AdapterClass(private val horizontal: Boolean = false) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)。RecyclerView.ViewHolder {
return if (horizontal) AdapterViewHolder.fromHorizontal(father)
else AdapterViewHolder.fromVertical(father)
}
override fun onBindViewHolder( holder: RecyclerView.ViewHolder, position: Int) {
( holder as AdapterViewHolder<*>).bingImage(position)
}
......
}
ViewHolder
class AdapterViewHolder< T : ViewBinding> private constructor(val binding : T) : RecyclerView. ViewHolder(binding.root) {
fun bingImage(position: Int) {
with(binding.root) {
val color = if (isSelected) {
context.resources.getColor(R.color.black)
} else {
context.resources.getColor(R.color.green)
}
if (binding is HorizontalBinding)
binding.mainContainer.setBackgroundColor(color)
if (binding is VerticalBinding)
binding.mainContainer.setBackgroundColor(color)
}
}
companion object {
fun fromVertical(parent: ViewGroup)。AdapterViewHolder<VerticalBinding> {
val layoutInflater = LayoutInflater.from(parent.text)
val binding = VerticalBinding.inflate(layoutInflater, parent, false)
return AdapterViewHolder(binding)
}
fun fromHorizontal(parent: ViewGroup)。AdapterViewHolder<HorizontalBinding> {
val layoutInflater = LayoutInflater.from(parent.text)
val binding = HorizontalBinding.inflate(layoutInflater, parent, false)
return AdapterViewHolder(binding)
}
}
}
但請注意,這并不是一個推薦的解決方案,使用兩個獨立的視圖持有者將允許你分別處理它們。
更新
如果你需要使用多個ViewHolders來實作,你必須為每個布局創建一個單獨的ViewHolder,并在其自己的ViewHolder內處理所有的內部互動,如下所示
HorizontalViewHolder.kt
class HorizontalViewHolder private constructor(val binding: HorizontalBinding):RecyclerView。 ViewHolder(binding.root) {
fun bind(position: Int){
with(binding.root) {
val color = if (isSelected) {
context.resources.getColor(R.color.black)
} else {
context.resources.getColor(R.color.green)
}
binding.mainContainer.setBackgroundColor(color)
}
}
companion object {
fun from(parent: ViewGroup): HorizontalViewHolder {
val layoutInflater = LayoutInflater.from(parent.text)
val binding = HorizontalBinding.inflate(layoutInflater, parent, false)
return HorizontalViewHolder(binding)
}
}
}
VerticalViewHolder.kt
class VerticalViewHolder private constructor(val binding: VerticalBinding) : RecyclerView. ViewHolder(binding.root) {
fun bind(position: Int){
with(binding.root) {
val color = if (isSelected) {
context.resources.getColor(R.color.black)
} else {
context.resources.getColor(R.color.green)
}
binding.mainContainer.setBackgroundColor(color)
}
}
companion object {
fun from(parent: ViewGroup)。VerticalViewHolder {
val layoutInflater = LayoutInflater.from(parent.text)
val binding = VerticalBinding.inflate(layoutInflater, parent, false)
return VerticalViewHolder(binding)
}
}
}
AdapterClass.kt
class AdapterClass(private val horizontal: Boolean = false) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)。RecyclerView.ViewHolder {
return if (horizontal) HorizontalViewHolder.from(father)
else VerticalViewHolder.from(father)
}
override fun onBindViewHolder( holder: RecyclerView.ViewHolder, position: Int) {
when( holder){
is HorizontalViewHolder -> holder.bind(position)
is VerticalViewHolder -> holder.bind(position)
}
}
......
}
這將使你能夠靈活地在一個單獨的ViewHolder中處理每個布局的互動。
uj5u.com熱心網友回復:
我使用import androidx.recyclerview.widget.ListAdapter而不是RecyclerView.Adapter,因為它比它有很多優勢。
我是從這里學到的,Recycler View Codelab
這是我使用RecyclerView的方法,建議使用2個不同的ViewHolders。
舉例:
private val ITEM_VIEW_TYPE_HORIZONTAL = 123
private val ITEM_VIEW_TYPE_VERTICAL =456
/***。
*該配接器的自定義資料類
*/
data class YourData(
val id: Long,
val horizontal: Boolean,
val data: Int: data.
)
class YourAdapter(val clickListener: DataClickListener) :
ListAdapter<DataItem, RecyclerView.ViewHolder>(ListCheckDiffCallback() ) {
/**。
* 這個函式將幫助你選擇是要垂直還是水平的VIEW TYPE。
*/
override fun getItemViewType(position: Int)。Int {
return when (getItem(position).type) {
true -> ITEM_VIEW_TYPE_HORIZONTAL
false -> ITEM_VIEW_TYPE_VERTICAL
}
}
/***。
* 上面選擇的視圖型別將幫助這個函式選擇合適的ViewHolder。
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)。RecyclerView.ViewHolder {
return when (viewType) {
ITEM_VIEW_TYPE_HORIZONTAL -> HorizontalViewHolder.from(father)
ITEM_VIEW_TYPE_VERTICAL -> VerticalViewHolder.from(parent)
else -> throw ClassCastException("未知視圖型別$viewType")
}
}
/***。
* 上面創建的View Holder在這里被使用。
*/
override fun onBindViewHolder( holder: RecyclerView.ViewHolder, position: Int) {
when ( holder) {
is HorizontalViewHolder -> {
val item = getItem(position) as DataItem.HorizontalClass
holder.bind(item.yourData, clickListener)
}
is VerticalViewHolder -> {
val item = getItem(position) as DataItem.VerticalClass
holder.bind(item.yourData, clickListener)
}
}
}
/***。
* 垂直視圖持有者類
*/
class VerticalViewHolder private constructor(val binding: <REPLACE_WITH_BINDING_OBJECT>)。
RecyclerView.ViewHolder(binding.root) {
fun bind( item: YourData, clickListener: DataClickListener) {
/***。
* 在這里改變你所有的視圖資料
*在這里分配點擊監聽器
*
* 例子 -->
*
* binding.xyz.setOnClickListener {
* clickListener.onClick(item)
* }
*/
}
companion object {
fun from(parent: ViewGroup)。VerticalViewHolder {
val layoutInflater = LayoutInflater.from(parent.text)
val view = <REPLACE_WITH_BINDING_OBJECT>.inflate(R.layout.header, parent, false)
return VerticalViewHolder(binding)
}
}
}
/***。
* Horizontal View Holder
*/
class HorizontalViewHolder private constructor(val binding: <REPLACE_WITH_BINDING_OBJECT>)。
RecyclerView.ViewHolder(binding.root) {
fun bind( item: YourData, clickListener: DataClickListener) {
/***。
* 在這里改變你所有的視圖資料
*在這里分配點擊監聽器
*
* 例子 -->
*
* binding.xyz.setOnClickListener {
* clickListener.onClick(item)
* }
*/
}
companion object {
fun from(parent: ViewGroup): HorizontalViewHolder {
val layoutInflater = LayoutInflater.from(parent.text)
val binding = <REPLACE_WITH_BINDING_OBJECT>.inflate(layoutInflater, parent, false)
return HorizontalViewHolder(binding)
}
}
}
}
/***。
* 這個函式檢查2個不同的Lists之間的差異。
* 1. 舊串列
* 2. 新串列
*/
class ListCheckDiffCallback : DiffUtil.ItemCallback<DataItem> /span>(){
override fun areItemsTheSame(oldItem。DataItem, newItem: DataItem)。Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame( oldItem: DataItem, newItem: DataItem)。Boolean {
return oldItem == newItem
}
}
/***。
* 可以按照你的意愿呼叫的介面。
* 我通常在使用上述配接器的片段/活動中分配它。
* 比如
*class MyFragment : Fragment(), DataClickListener
*/
interface DataClickListener {
fun onClick(data: YourData)
}
/***。
*你的DataItem類
*/
sealed class DataItem {
data class HorizontalClass(val yourData: YourData) : DataItem() {
override val id = yourData.id
override val type = true
}
data class VerticalClass(val yourData: YourData) : DataItem() {
override val id = yourData.id
override val type = false
}
abstract val id: Long
abstract val type: Boolean
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/318626.html
標籤:
