Честно говоря, я не знаю, что делал весь этот код, который вы опубликовали выше, слишком долго, слишком мало смысла, даже не знаю, как он работал.
Из любопытства, я собираюсьПопробуйте решить эту проблему прямо здесь, я надеюсь, что это работает.
Сначала метод onMeasure()
:
// maximum available width for children
int maxW = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
// you want all children to be as wide as they want, but not wider than the view group
int widthMS = MeasureSpec.makeMeasureSpec(w, MeasureSpec.AT_MOST);
// you probably want them all to have the same height.
// maybe define it in xml attrs?
int heightMS = MeasureSpec.makeMeasureSpec(rowHeight, MeasureSpec.EXACTLY);
// remaining width of current row, initially equals to w
int remW = w;
// index of first child in the current row
int rowFirstChild = 0;
// row count, used to calculate the view group's height
int rows = 0;
int i = 0;
while (i < getChildCount()) {
Child ch = getChildAt(i);
if (ch.getVisibility() != View.GONE) {
// ask how big does it want to be
child.measure(widthMS, heightMS);
int chWidth = ch.getMeasuredWidth();
// if it fits
if (remW - chWidth >= 0) {
// update remW, then go to next child
remW -= chWidth;
i++;
}
// if it does not fit
else {
// if it's not the first child in the row
if (i > rowFirstChild) {
stretchViews(rowFirstChild, i - 1, maxW, remW, heightMS);
// this will be the first child in the next row and take the space from
// that row's remW
rowFirstChild = i;
remW = maxW - chWidth;
}
// if it's the first and only child on this row
else {
// it should just take the full width and give first spot in the next
// row to the next child, and reset remW
rowFirstChild = i + 1;
remW = maxW;
}
// both of these scenarios result in the addition of a new row
rows++;
}
}
}
// finally, we want to take as much width as we can, and as minimum height as we can
int finalW = MeasureSpec.getSize(widthMeasureSpec);
int finalH = Math.min(
rows * rowHeight + getPaddingTop() + getPaddingBottom(),
MeasureSpec.getSize(heightMeasureSpec)
);
setMeasuredDimensions(finalW, finalH);
// note that this measurement ignores height measure spec and automatically takes the
// minimum height, and ignores the height measure spec of its children as well and
// just gives them height from its rowHeight attr.
// you are free to change this setting.
Теперь, onLayout()
метод.Здесь, поскольку мы уже присвоили измерения нашим детям, они все настроены, мы просто должны их выложить, а не много работы:
// maximum usable width in any row
int maxW = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
// left starting point
int left = getPaddingLeft();
// top starting point
int top = getPaddingTop();
int i = 0;
while (i < getChildCount()) {
Child ch = getChildAt(i);
if (ch.getVisibility() != GONE) {
int chWidth = ch.getMeasuredWidth();
ch.layout(
left,
top,
left + chWidth,
top + rowHeight
);
// if this child is the last in row (-1 for error tolerance when rounding ints)
if (left + chWidth >= maxW - 1) {
// reset'left' back to its starting point
left = getPaddingLeft();
// move 'top' down by 'rowHeight'
top += rowHeight;
}
// if it wasn't the last child in the row
else {
// then simply advance the 'left' position
left += chWidth;
}
}
}
// Note that this method only supports LTR layout.
// You can make minor changes to add support for RTL.
// Also, margins between children are ignored, spend some time on that if you want
Дайте мне знать, если это работает
Обновление:
Неважно, я все равно просто сделаю метод растяжения:
/**
* Stretches children of this view group horizontally, and proportionally to their widths
* to span the entire row width
*
* @param firstIndex index of first child to stretch (inclusive)
* @param lastIndex index of last child to stretch (inclusive)
* @param fullWidth the width to cover (max available width for row children)
* @param remWidth remaining width to cover
* @param heightMS the hight measure spec to reuse on these views
*/
private void stretchViews(int firstIndex, int lastIndex, int fullWdith, int
remWidth, int heightMS) {
for (int i = firstIndex; i <= lastIndex; i++) {
Child ch = getChildAt(i);
if (ch.getVisibility() != GONE) {
int measuredW = ch.getMeasuredWidth();
int widthMS = MeasureSpec.makeMeasureSpec(
measuredW + remWidth * measuredW / fullWidth, MeasureSpec.EXACTLY);
ch.measure(widthMS, heightMS);
}
}
}