I extend com.google.android.material.chip.Chip
I have a text which I measure while in onMeasure.
My calculation says the text can fit in the chip's space, but in reality I see the text is truncated.
I would expect no truncation, as I measure before layout pass.
*I use the biggest display size, largest font size, Ukraine fonts.
Should I change my measurement code somehow?
private String getLongestPossibleChipText(int textMaxWidth) {
final MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
final View parent = (View) getParent();
final int parentPaddingLeft = parent.getPaddingLeft();
final int parentPaddingRight = parent.getPaddingRight();
final int paddingLeft = getPaddingLeft();
final int paddingRight = getPaddingRight();
final int leftMargin = layoutParams.leftMargin;
final int rightMargin = layoutParams.rightMargin;
final int currentTextMaxWidth =
parentWidth
- (parentPaddingLeft
+ parentPaddingRight
+ paddingLeft
+ paddingRight
+ leftMargin
+ rightMargin);
final TextPaint paint = getPaint();
for (String chipText : chipTexts) {
if (paint.measureText(chipText) <= currentTextMaxWidth) {
return chipText;
}
}
return Iterables.getLast(chipTexts);
}
I don't think that the text length is being computed correctly. From the documentation for ChipDrawable there is some internal structure to Chip that I don't think the code is accounting for. (Chip is a wrapper for ChipDrawable.) I will reproduce the diagram here:

It could be that the internal padding is all zero, so it won't matter. Nonetheless, the calculateTextBounds() method from ChipDrawable might be a good starting point.
The following code should compute the text space available within a Chip correctly and pick the string with the best fit. The candidates array must be sorted in ascending order by string length. Under certain circumstances, another character may look like it would fit but it is the character spacing (which is part of the character) that isn't fitting. If this is a problem, it may be possible to get a better-looking fit by using Paint#getTextBounds().
private fun findBestFitForChip(chip: Chip, candidates: Array<String>): String {
val parent = chip.parent as ViewGroup
val maxChipWidth =
if (chip.layoutParams.width == ViewGroup.LayoutParams.WRAP_CONTENT) {
parent.width - parent.paddingStart - parent.paddingEnd - chip.marginStart - chip.marginEnd
} else {
chip.width
}
val chipSizeLessText =
with(chip) {
// Keep the parentheses
(chipStartPadding
+ iconStartPadding
+ chipIconSize
+ iconEndPadding
+ textStartPadding
+ textEndPadding
+ closeIconStartPadding
+ closeIconSize
+ closeIconEndPadding
+ chipEndPadding)
}
val currentTextMaxWidth = maxChipWidth - chipSizeLessText
val paint: TextPaint = chip.paint
var result = ""
for (i in (candidates.size - 1) downTo 0) {
if (paint.measureText(candidates[i]) <= currentTextMaxWidth) {
result = candidates[i]
break
}
}
return result
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With