为什么ChipGroup在HorizontalScrollView中,Chip的边距端不起作用?



我在ChipGroup中有芯片,而这个ChipGroup在HorizontalScrollView中。但我的问题是marginEnd在最后一个芯片不工作!

我尝试通过编程更改布局参数,但没有成功

<HorizontalScrollView
android:id="@+id/chips_container"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_gravity="center_vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/dividerSmartReplies"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible">
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
app:chipSpacing="8dp"
app:singleLine="true"
app:singleSelection="true">
<com.google.android.material.chip.Chip
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:layout_marginStart="8dp"
android:textColor="@color/selector_smart_reply_chip_text"
app:checkedIconVisible="false"
app:chipBackgroundColor="@color/selector_smart_reply_chip"
app:chipCornerRadius="21dp"
app:chipStrokeColor="@color/app_base_blue"
app:chipStrokeWidth="1dp" />
<com.google.android.material.chip.Chip
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:textColor="@color/selector_smart_reply_chip_text"
app:checkedIconVisible="false"
app:chipBackgroundColor="@color/selector_smart_reply_chip"
app:chipCornerRadius="21dp"
app:chipStrokeColor="@color/app_base_blue"
app:chipStrokeWidth="1dp" />
<com.google.android.material.chip.Chip
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:textColor="@color/selector_smart_reply_chip_text"
app:checkedIconVisible="false"
app:chipBackgroundColor="@color/selector_smart_reply_chip"
app:chipCornerRadius="21dp"
app:chipStrokeColor="@color/app_base_blue"
app:chipStrokeWidth="1dp" />
<com.google.android.material.chip.Chip
style="@style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="wrap_content"
android:layout_height="42dp"
android:layout_marginEnd="8dp"
android:textColor="@color/selector_smart_reply_chip_text"
app:checkedIconVisible="false"
app:chipBackgroundColor="@color/selector_smart_reply_chip"
app:chipCornerRadius="21dp"
app:chipStrokeColor="@color/app_base_blue"
app:chipStrokeWidth="1dp" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>

在最后一个Chip之后我需要额外的空间。ChipGroup的填充工作,但它不期望UI结果。

嘿,我知道这有点晚了,我很高兴你找到了一个适合你的答案。然而,我认为我有一个更好的解决方案:

  • 在HorizontalScrollView中添加8dp开始和结束填充
  • 将clipToPadding设为false

所以这就是您的HorizontalScrollView应该是什么样子:

<HorizontalScrollView
android:id="@+id/chips_container"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_gravity="center_vertical"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/dividerSmartReplies"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:clipToPadding="false"
>

您可以删除第一个和最后一个芯片的边距!

我发现了这个问题!ChipGroup扩展FlowLayout。在onMeasure()方法中,FlowLayout不考虑finalWidth的最后一个子项的marginRight
我的最终解决方案:

class SmartRepliesGroup @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyle: Int = 0
) : ChipGroup(context, attributeSet, defStyle) {
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val width = MeasureSpec.getSize(widthMeasureSpec)
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val height = MeasureSpec.getSize(heightMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val maxWidth =
if (widthMode != -2147483648 && widthMode != 1073741824) 2147483647 else width
var childLeft = this.paddingLeft
var childTop = this.paddingTop
var childBottom = childTop
var maxChildRight = 0
val maxRight = maxWidth - this.paddingRight
var finalWidth = 0
var lastChildMarginRight = 0
while (finalWidth < this.childCount) {
val child = this.getChildAt(finalWidth)
if (child.visibility != 8) {
this.measureChild(child, widthMeasureSpec, heightMeasureSpec)
val lp = child.layoutParams
var leftMargin = 0
var rightMargin = 0
if (lp is MarginLayoutParams) {
leftMargin += lp.leftMargin
rightMargin += lp.rightMargin
lastChildMarginRight = rightMargin
}
var childRight = childLeft + leftMargin + child.measuredWidth
if (childRight > maxRight && !this.isSingleLine) {
childLeft = this.paddingLeft
childTop = childBottom + this.lineSpacing
}
childRight = childLeft + leftMargin + child.measuredWidth
childBottom = childTop + child.measuredHeight
if (childRight > maxChildRight) {
maxChildRight = childRight
}
childLeft += leftMargin + rightMargin + child.measuredWidth + this.itemSpacing
}
++finalWidth
}
finalWidth =
getMeasuredDimension(width, widthMode, maxChildRight + lastChildMarginRight)
val finalHeight = getMeasuredDimension(height, heightMode, childBottom)
this.setMeasuredDimension(finalWidth, finalHeight)
}
private fun getMeasuredDimension(size: Int, mode: Int, childrenEdge: Int): Int =
when (mode) {
-2147483648 -> Math.min(childrenEdge, size)
1073741824 -> size
else -> childrenEdge
}
}

最新更新