【问题标题】:Make horizontal RecyclerView first and last item with rounded corner使用圆角制作水平 RecyclerView 第一个和最后一个项目
【发布时间】:2022-01-09 10:23:57
【问题描述】:

recyclerView 中的所有图片都是方形的。我必须为 recyclerView 提供角半径,但内部项目是方形的

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

有没有办法在android中轻松地舍入第一个和最后一个项目

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 设置为我的 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>

【问题讨论】:

    标签: android kotlin android-recyclerview rounded-corners


    【解决方案1】:

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

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

    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为背景)

    【讨论】:

      【解决方案2】:

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

      1. 将这些添加到您的模型数据类中:
      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...
          }
      }
      

      【讨论】:

      • 感谢@Milad Mohammadi
      • 乐于帮助@TaimoorKhan
      【解决方案3】:

      您可以在onCreateViewHolder 方法中使用RecyclerViewAdapterviewType。 您覆盖 getItemViewType(int position) 方法并按位置返回不同的“类型”。 在onCreateViewHolder 方法中,您可以扩展不同的布局或将不同的设置应用于视图。

      查看此链接:https://blog.mindorks.com/recyclerview-multiple-view-types-in-android

      【讨论】:

      • @Yaov Gibri 物品装饰没有简单的方法
      • @TaimoorKhan 你是什么意思?这正是我在我的项目中所做的。这就像 milad Mohammadi 的回答。
      猜你喜欢
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 2019-03-12
      • 2019-01-01
      • 1970-01-01
      • 2020-12-23
      • 2018-02-10
      • 1970-01-01
      相关资源
      最近更新 更多