制作带圆角的水平 RecyclerView 第一个和最后一个项目

Make horizontal RecyclerView first and last item with rounded corner

All images inside recyclerView are in square shape. I have to provide corner radius to recyclerView but the inner items are square

我尝试给 recyclerview 一个形状但无法实现

有没有办法在 android easy

中舍入第一项和最后一项

round_recycler.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/white"/>

    <stroke android:width="1dp"
        android:color="@android:color/transparent"
        />

    <padding android:left="8dp"
        android:top="8dp"
        android:right="8dp"
        android:bottom="8dp"
        />

    <corners android:bottomRightRadius="7dp"
        android:bottomLeftRadius="7dp"
        android:topLeftRadius="7dp"
        android:topRightRadius="7dp"/>
</shape>

只有我必须四舍五入第一个和最后一个项目或 RecylerView 我也尝试 clipOutline true 到我的 item_row_layout

item_row_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <import type="android.view.View" />
        <variable
            name="item"
            type="planet.beyond.domain.models.RecentBO" />

    </data>

    <planet.beyond.gallerycleanarchitecture.utis.AspectRatioImageView
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/ivPhoto"
        imagePath="@{item.imageUrl}"
        android:layout_width="90dp"
        android:clipToOutline="true"
        android:layout_height="90dp"
        android:foreground="?android:attr/selectableItemBackground"
        android:scaleType="centerCrop"
        tools:src="@tools:sample/avatars" />
</layout>

您可以在onCreateViewHolder方法中使用RecyclerViewAdapterviewType。 您按位置覆盖 getItemViewType(int position) 方法和 return 不同的“类型”。 在 onCreateViewHolder 方法中,您可以展开不同的布局或对视图应用不同的设置。

检查此 link:https://blog.mindorks.com/recyclerview-multiple-view-types-in-android

由于您使用的是 Kotlin 和 DataBinding,执行此类操作的一种简单方法可能是映射您的项目集合以确定哪个是第一个项目,哪个是最后一个项目。

有很多方法可以执行此操作,为了简单起见,我将只提供一个包装器 class 来说明我将如何解决该问题:

data class RecentBOItem(
  val data: RecentBO,
  val isFirst: Boolean,
  val isLast: Boolean
)

让视图模型执行如下操作:

suspend fun getSomething(): List<RecentBOItem> {
  val recentBos = getRecentBOsFromNetwork()
  val lastIndex = recentBos.lastIndex
  return recent.withIndex().map { (index, recentBo) ->
    RecentBOItem(
      data = recentBo,
      isFirst = index == 0,
      isLast = index == lastIndex
    )
  }
}

然后为 RecentBOItem 提供 @BindingAdapter,根据 isFirstisLast 标志设置圆角形状。 (也就是设置合适的R.drawable作为背景)

我给你两种方法,你可以根据自己的需要选择

  1. 将这些添加到您的模型数据中 class:
val isFirst: Boolean = false,
val isLast: Boolean = false

并在您的 onBindViewHolder 中根据您之前为项目定义的变量进行操作。

  1. 定义不同的视图类型并根据您的视图类型显示项目布局。 这是一个展示其工作原理的示例: ‍‍‍‍‍‍
class SampleAdapter: RecyclerView.Adapter<SampleAdapter.ViewHolder>() {
    // I consider you are using DiffUtil, change the implementation based on your adapter structure

    companion object {
        private const val VIEW_TYPE_FIRST = -1
        private const val VIEW_TYPE_MIDDLE = 0
        private const val VIEW_TYPE_LAST = 1
    }

    override fun getItemViewType(position: Int): Int {
        return when {
            position == 0 -> VIEW_TYPE_FIRST
            position == differ.currentList.size - 1 -> VIEW_TYPE_LAST
            else -> VIEW_TYPE_MIDDLE
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return when {
            VIEW_TYPE_FIRST -> ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_first_row_layout, parent, false))
            VIEW_TYPE_LAST -> ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_last_row_layout, parent, false))
            else -> ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_middle_row_layout, parent, false))
        }
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val viewType = getItemViewType(position)

        holder.itemView.apply {
            when (viewType) {
                VIEW_TYPE_FIRST -> loadFirstItem(this)
                VIEW_TYPE_MIDDLE -> loadMiddleItem(this, position)
                VIEW_TYPE_LAST -> loadLastItem(this)
            }
        }
    }


    private fun loadFirstItem(itemView: View) {
        val item = differ.currentList[0]
        // your code...
    }

    private fun loadMiddleItem(itemView: View, position: Int) {
        val item = differ.currentList[position]
        // your code...
    }

    private fun loadLastItem(itemView: View) {
        val item = differ.currentList.last()
        // your code...
    }
}