Android: разрыв строки в горизонтальном списке с ярлыками, похожими на трелло - PullRequest
0 голосов
/ 23 мая 2018

Я хочу создать представление в Android, которое будет содержать метки, как это делает Trello.card with labels

Проблема, с которой я сталкиваюсь, заключается в том, как создать новый разрыв строки, когда держатель этикетки достигнет максимальной ширины.Я хочу добиться чего-то подобного.

card with labels that surpass the view's width capacity card with labels that surpass the view's width capacity twice

Также необходимо учитывать, что метки могут иметь разную ширину длины.

Я пришел к идее надувать новый горизонтальный вид каждый раз, когда сумма ширины превышает максимальную емкость, но я не знаю, существует ли другой подход или более эффективный способ решения этой проблемы.

possible solution diagram

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Просто настройте ViewGroup, переопределив onLayout и метод onMeasure:

String[] dataList;

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childCount = getChildCount();
    int curItemWidth, curItemHeight, curLeft, curTop, maxHeight;

    //get the available size of child view
    int viewLeft = this.getPaddingLeft();
    int viewTop = this.getPaddingTop();
    int viewRight = this.getMeasuredWidth() - this.getPaddingRight();
    int viewBottom = this.getMeasuredHeight() - this.getPaddingBottom();
    int viewWidth = viewRight - viewLeft;
    int viewHeight = viewBottom - viewTop;

    maxHeight = 0;
    curLeft = viewLeft + getCurLeft(0, viewWidth, viewHeight, viewRight);
    curTop = viewTop;

    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);

        if (child.getVisibility() == GONE)
            continue;

        //Get the maximum size of the child
        child.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.AT_MOST),
                MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.AT_MOST));

        curItemWidth = child.getMeasuredWidth();
        curItemHeight = child.getMeasuredHeight();
        //wrap is reach to the end
        if (curLeft + curItemWidth >= viewRight) { //new row
            curLeft = viewLeft + getCurLeft(i, viewWidth, viewHeight, viewRight);
            curTop += maxHeight;
            maxHeight = 0;
        }
        //do the layout
        child.layout(curLeft, curTop, curLeft + curItemWidth, curTop + curItemHeight);

        //store the max height
        maxHeight = Math.max(maxHeight, curItemHeight);
        curLeft += curItemWidth;
    }
}

private int getCurLeft(int currentPosition, int viewWidth, int viewHeight, int viewRight) {
    int childCount = getChildCount();
    int currentMaxWidth = 0;
    for (int i = currentPosition; i < childCount; i++) {
        View child = getChildAt(i);
        if (child.getVisibility() == GONE)
            continue;

        child.measure(MeasureSpec.makeMeasureSpec(viewWidth, MeasureSpec.AT_MOST),
                MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.AT_MOST));

        currentMaxWidth += child.getMeasuredWidth();
        //wrap is reach to the end
        if (currentMaxWidth >= viewRight) { //new row
            return 0;
        }
    }
    return (viewWidth - currentMaxWidth) / 2;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // Measurement will ultimately be computing these values.
    int childCount = getChildCount();
    int maxHeight = 0;
    int maxWidth = 0;
    int childState = 0;
    int currentRowWidth = 0;
    int parentWidth = resolveSizeAndState(maxWidth, widthMeasureSpec, childState);
    // Iterate through all children, measuring them and computing our dimensions
    // from their size.

    for (int i = 0; i < childCount; i++) {
        View child = getChildAt(i);

        if (child.getVisibility() == GONE)
            continue;

        // Measure the child.
        measureChild(child, widthMeasureSpec, heightMeasureSpec);
        maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
        maxHeight = Math.max(maxHeight, child.getMeasuredHeight());

        currentRowWidth += child.getMeasuredWidth();
        if (currentRowWidth >= parentWidth) { //create new row.
            maxHeight += child.getMeasuredHeight();
            currentRowWidth = 0;
        }
        childState = combineMeasuredStates(childState, child.getMeasuredState());
    }

    // Check against our minimum height and width
    maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
    maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

    // Report our final dimensions.
    setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
            resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}

public void setData(String[] dataList) {
    this.dataList = dataList;

    for (int i = 0; i < dataList.length; i++) {
        View tagView = layoutInflater.inflate(R.layout.item_tag_layout, null, false);

        TextView tagTextView = tagView.findViewById(R.id.label);
        tagTextView.setText(dataList[i]);
        tagTextView.setTag(i);
        tagTextView.setOnClickListener(onClickListener);

        if (dataList[i].equalsIgnoreCase(defaultItem)) {
            selectedItemView = tagTextView;
            tagTextView.setTextColor(ContextCompat.getColor(getContext(), R.color.tag_layout_text_selected));
        } else {
            tagTextView.setTextColor(ContextCompat.getColor(getContext(), R.color.tag_layout_text_default));
        }

        if (i == dataList.length - 1) {
            View indicator = tagView.findViewById(R.id.indicator);
            indicator.setVisibility(GONE);
        }
        this.addView(tagView);
    }

}
0 голосов
/ 23 мая 2018

В этом случае, я думаю, вы должны использовать это и заменить RecyclerView.

...