如何将 Gridlayoutmanager 用于 recyclerView 内的可扩展卡片
Posted
技术标签:
【中文标题】如何将 Gridlayoutmanager 用于 recyclerView 内的可扩展卡片【英文标题】:How to use Gridlayoutmanager for expandable cards inside a recyclerView 【发布时间】:2021-05-17 22:07:12 【问题描述】:我正在尝试使用可扩展卡片制作网格布局,但问题是当卡片展开时,它的高度会变大,行中其他卡片的高度也会变大(以匹配第一张卡片的高度) card),但是当卡片向后折叠时,所有卡片的高度都不会像展开时一样发生变化。有谁知道可能是什么问题?
编辑:
recyclerview_item.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView 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:id="@+id/cardView"
android:layout_
android:layout_
app:cardBackgroundColor="@color/misty_rose"
android:layout_margin="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_
android:layout_>
<!-- Media -->
<ImageView
android:id="@+id/imageView"
android:layout_
android:layout_
android:layout_gravity="center_horizontal"
android:padding="8dp"
android:contentDescription="Photo"
android:src="@drawable/unsplash"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="@color/isabelline"
/>
<!-- Title, secondary and supporting text -->
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_
android:layout_
android:background="@color/misty_rose"
app:layout_constraintTop_toBottomOf="@+id/imageView"
android:padding="8dp">
<TextView
android:id="@+id/textViewCode"
android:layout_
android:layout_
android:text="Code"
android:textAppearance="?attr/textAppearanceHeadline6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatImageButton
android:id="@+id/iconExpandCard"
android:layout_
android:layout_
android:padding="8dp"
android:src="@drawable/ic_baseline_expand_more_36"
android:background="?attr/selectableItemBackgroundBorderless"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<TextView
android:id="@+id/textViewDescription"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:text="Description"
android:textAppearance="?attr/textAppearanceBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewCode" />
<TextView
android:id="@+id/textViewPrice"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:text="Price"
android:textAppearance="?attr/textAppearanceBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewDescription"/>
<TextView
android:id="@+id/textViewComment"
android:layout_
android:layout_
android:layout_marginTop="8dp"
android:text="Comment"
android:textAppearance="?attr/textAppearanceBody1"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewPrice"
android:visibility="gone"/>
<!-- Buttons -->
<LinearLayout
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_marginTop="8dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewComment">
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonMinusArticle"
style="?attr/borderlessButtonStyle"
android:layout_
android:layout_
android:layout_marginEnd="16dp"
android:
android:minWidth="40dp"
android:backgroundTint="@color/purple_200"
android:text="@string/minus"
android:textColor="@color/white" />
<EditText
android:id="@+id/editNumberOfProducts"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_marginEnd="16dp"
android:inputType="numberDecimal|number"
android:text="@string/zero"
android:textAppearance="?attr/textAppearanceBody1"
android:textColor="?android:attr/textColorSecondary"
android:textSize="18sp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/buttonPlusArticle"
style="?attr/borderlessButtonStyle"
android:layout_
android:layout_
android:
android:minWidth="40dp"
android:backgroundTint="@color/purple_200"
android:text="@string/plus"
android:textColor="@color/white" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
在 ProductListAdapter.kt 中(重要的部分在 expandButton.setOnClickListener() 中):
class ProductListAdapter() : ListAdapter<Product, ProductListAdapter.ProductViewHolder>(ProductsComparator())
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProductViewHolder
return ProductViewHolder.create(parent)
override fun onBindViewHolder(holder: ProductViewHolder, position: Int)
val current = getItem(position)
holder.bind(current!!)
class ProductViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
private val productItemView: TextView = itemView.findViewById(R.id.textViewCode)
private val productDescription : TextView = itemView.findViewById(R.id.textViewDescription)
private val productPrice : TextView = itemView.findViewById(R.id.textViewPrice)
fun bind(product: Product)
productItemView.text = product.code
//productDescription.text = product.description
//productPrice.text = "Price " + product.client_price.toString()
companion object
val mapOfProducts :HashMap<String, Int> = hashMapOf<String, Int>()
fun create(parent: ViewGroup): ProductViewHolder
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.recyclerview_item, parent, false)
val minusButton : Button = view.findViewById(R.id.buttonMinusArticle)
val plusButton : Button = view.findViewById(R.id.buttonPlusArticle)
val productItemViewCode: TextView = view.findViewById(R.id.textViewCode)
val expandButton : androidx.appcompat.widget.AppCompatImageButton = view.findViewById(R.id.iconExpandCard)
val commentView : TextView = view.findViewById(R.id.textViewComment)
val cardView : CardView = view.findViewById(R.id.cardView)
expandButton.setOnClickListener
if (commentView.visibility == View.GONE)
TransitionManager.beginDelayedTransition(cardView, AutoTransition())
commentView.visibility = View.VISIBLE
expandButton.setImageResource(R.drawable.ic_baseline_expand_less_36)
else
TransitionManager.beginDelayedTransition(cardView, AutoTransition())
commentView.visibility = View.GONE
expandButton.setImageResource(R.drawable.ic_baseline_expand_more_36)
val editNumberOfProducts: EditText = view.findViewById(R.id.editNumberOfProducts)
editNumberOfProducts.doAfterTextChanged
val code = productItemViewCode.text.toString()
if (it.isNullOrBlank())
modifyText("0", view)
mapOfProducts.remove(code)
return@doAfterTextChanged
val originalText = it.toString()
try
val number = originalText.toInt()
val numberText = originalText.toInt().toString()
if (originalText != numberText)
modifyText(numberText, view)
if (number > 0)
mapOfProducts[code] = number
d("CodeOfView", "$code $number")
else
mapOfProducts.remove(code)
catch (e: Exception)
modifyText("0", view)
mapOfProducts.remove(code)
minusButton.setOnClickListener
var number = editNumberOfProducts.text.toString().toInt()
if (number>0)
number -= 1
modifyText(number.toString(), view)
plusButton.setOnClickListener
//val code = productItemViewCode.text.toString()
var number = editNumberOfProducts.text.toString().toInt()
number += 1
modifyText(number.toString(), view)
return ProductViewHolder(view)
private fun modifyText(numberText: String, view: View)
val editNumberOfProducts = view.findViewById<EditText>(R.id.editNumberOfProducts)
editNumberOfProducts.setText(numberText)
editNumberOfProducts.setSelection(numberText.length)
class ProductsComparator : DiffUtil.ItemCallback<Product>()
override fun areItemsTheSame(oldItem: Product, newItem: Product): Boolean
return oldItem === newItem
override fun areContentsTheSame(oldItem: Product, newItem: Product): Boolean
return oldItem.code == newItem.code
Example with images of the problem
【问题讨论】:
嗨 Gheorghe, 仅通过阅读您的文字很难说出问题所在,如果您分享您的代码和您正在尝试的内容的快照,那就太好了。去做。 嗨@ajay,感谢您的回复,我刚刚编辑了问题 确保您使用的是 Adapter.notifyDataSetChanged()。那应该可以解决这个问题。让我知道这是否能解决您的问题。 @AjayJG 谢谢!它解决了我的问题!这是我第一次为 android 做东西,所以我最初不知道在哪里使用 notifyDataSetChanged(),所以我认为它不起作用,但经过一些更改它修复了所有问题。 【参考方案1】:我遇到了同样的问题,在我的情况下是垂直可扩展卡,我设法通过使用来解决它
Adapter.notifyDataSetChanged()
在正确的地方。
【讨论】:
以上是关于如何将 Gridlayoutmanager 用于 recyclerView 内的可扩展卡片的主要内容,如果未能解决你的问题,请参考以下文章
如何将gridlayoutManager每列的宽度设置为wrapContent在android中不固定大小
如何将 GridLayoutManager 中的项目固定为具有不同跨度计数的父项的开始和结束
如何摆脱 GridLayoutManager 项目之间的差距
RecyclerView GridLayoutManager:如何自动检测跨度计数?