Android Open Source - android-bubble-text Row Layout






From Project

Back to project page android-bubble-text.

License

The source code is released under:

MIT License

If you think the Android project android-bubble-text listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.asolutions.widget;
//from  w ww.j a  v  a  2  s. c o  m
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;

import com.oliveira.bubble.R;

public class RowLayout extends ViewGroup {

    public static final int DEFAULT_HORIZONTAL_SPACING = 6;
    public static final int DEFAULT_VERTICAL_SPACING = 0;

    private final int horizontalSpacing;
    private final int verticalSpacing;

    private List<RowMeasurement> mRows;
    private RowMeasurement mCurrentRow;
    private List<RowMeasurement> currentRows = Collections.emptyList();

    public RowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        mRows = new ArrayList<RowMeasurement>();
        mCurrentRow = new RowMeasurement();

        Resources r = context.getResources();
        TypedArray styledAttributes = context.obtainStyledAttributes(attrs, R.styleable.RowLayout);

        int hSpace = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                DEFAULT_HORIZONTAL_SPACING,
                r.getDisplayMetrics());

        int vSpace = (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP,
                DEFAULT_VERTICAL_SPACING,
                r.getDisplayMetrics());

        horizontalSpacing = styledAttributes.getDimensionPixelSize(
                R.styleable.RowLayout_android_horizontalSpacing,
                hSpace);

        verticalSpacing = styledAttributes.getDimensionPixelSize(
                R.styleable.RowLayout_android_verticalSpacing,
                vSpace);

        styledAttributes.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int maxInternalWidth = MeasureSpec.getSize(widthMeasureSpec) - getHorizontalPadding();
        final int maxInternalHeight = MeasureSpec.getSize(heightMeasureSpec) - getVerticalPadding();

        mRows.clear();
        mCurrentRow.setMaxWidth(maxInternalWidth);
        mCurrentRow.setWidthMode(widthMode);

        mRows.add(mCurrentRow);

        for (View child : getLayoutChildren()) {

            LayoutParams childLayoutParams = child.getLayoutParams();
            int childWidthSpec = createChildMeasureSpec(childLayoutParams.width, maxInternalWidth, widthMode);
            int childHeightSpec = createChildMeasureSpec(childLayoutParams.height, maxInternalHeight, heightMode);

            child.measure(childWidthSpec, childHeightSpec);

            int childWidth = child.getMeasuredWidth();
            int childHeight = child.getMeasuredHeight();

            if (mCurrentRow.wouldExceedMax(childWidth)) {
                mCurrentRow = new RowMeasurement(maxInternalWidth, widthMode);
                mRows.add(mCurrentRow);
            }

            mCurrentRow.addChildDimensions(childWidth, childHeight);
        }

        int longestRowWidth = 0;
        int totalRowHeight = 0;

        for (int index = 0; index < mRows.size(); index++) {

            RowMeasurement row = mRows.get(index);
            totalRowHeight += row.getHeight();

            if (index < mRows.size() - 1) {
                totalRowHeight += verticalSpacing;
            }

            longestRowWidth = Math.max(longestRowWidth, row.getWidth());
        }

        int measureWidth = widthMode == MeasureSpec.EXACTLY ?
                MeasureSpec.getSize(widthMeasureSpec) :
                longestRowWidth + getHorizontalPadding();

        int measureHeight = heightMode == MeasureSpec.EXACTLY ?
                MeasureSpec.getSize(heightMeasureSpec) :
                totalRowHeight + getVerticalPadding();

        setMeasuredDimension(measureWidth, measureHeight);
        currentRows = Collections.unmodifiableList(mRows);
    }

    private int createChildMeasureSpec(int childLayoutParam, int max, int parentMode) {

        int spec;
        if (childLayoutParam == LayoutParams.MATCH_PARENT) {
            spec = MeasureSpec.makeMeasureSpec(max, MeasureSpec.EXACTLY);
        } else if (childLayoutParam == LayoutParams.WRAP_CONTENT) {

            spec = MeasureSpec.makeMeasureSpec(
                    max,
                    parentMode == MeasureSpec.UNSPECIFIED ? MeasureSpec.UNSPECIFIED : MeasureSpec.AT_MOST);

        } else {
            spec = MeasureSpec.makeMeasureSpec(childLayoutParam, MeasureSpec.EXACTLY);
        }

        return spec;
    }

    @Override
    protected void onLayout(boolean changed, int leftPosition, int topPosition, int rightPosition, int bottomPosition) {

        final int widthOffset = getMeasuredWidth() - getPaddingRight();
        int x = getPaddingLeft();
        int y = getPaddingTop();

        Iterator<RowMeasurement> rowIterator = currentRows.iterator();
        RowMeasurement currentRow = rowIterator.next();

        for (View child : getLayoutChildren()) {

            final int childWidth = child.getMeasuredWidth();
            final int childHeight = child.getMeasuredHeight();

            if (x + childWidth > widthOffset) {
                x = getPaddingLeft();
                y += currentRow.height + verticalSpacing;
                if (rowIterator.hasNext()) {
                    currentRow = rowIterator.next();
                }
            }

            child.layout(x, y, x + childWidth, y + childHeight);
            x += childWidth + horizontalSpacing;
        }
    }

    private List<View> getLayoutChildren() {

        List<View> children = new ArrayList<View>();
        for (int index = 0; index < getChildCount(); index++) {
            View child = getChildAt(index);
            if (child.getVisibility() != View.GONE) {
                children.add(child);
            }
        }

        return children;
    }

    protected int getVerticalPadding() {
        return getPaddingTop() + getPaddingBottom();
    }

    protected int getHorizontalPadding() {
        return getPaddingLeft() + getPaddingRight();
    }

    private final class RowMeasurement {

        private int maxWidth;
        private int widthMode;
        private int width;
        private int height;

        public RowMeasurement() {

        }

        public RowMeasurement(int maxWidth, int widthMode) {
            this.maxWidth = maxWidth;
            this.widthMode = widthMode;
        }

        public void setMaxWidth(int maxWidth) {
            this.maxWidth = maxWidth;
        }

        public void setWidthMode(int widthMode) {
            this.widthMode = widthMode;
        }

        public int getHeight() {
            return height;
        }

        public int getWidth() {
            return width;
        }

        public boolean wouldExceedMax(int childWidth) {
            return widthMode != MeasureSpec.UNSPECIFIED && getNewWidth(childWidth) > maxWidth;
        }

        public void addChildDimensions(int childWidth, int childHeight) {
            width = getNewWidth(childWidth);
            height = Math.max(height, childHeight);
        }

        private int getNewWidth(int childWidth) {
            return width == 0 ? childWidth : width + horizontalSpacing + childWidth;
        }
    }
}




Java Source Code List

com.asolutions.widget.RowLayout.java
com.oliveira.bubble.AutoCompleteManager.java
com.oliveira.bubble.AutoCompletePopover.java
com.oliveira.bubble.AwesomeBubble.java
com.oliveira.bubble.BubbleSpanImpl.java
com.oliveira.bubble.BubbleSpan.java
com.oliveira.bubble.BubbleStyle.java
com.oliveira.bubble.ChipsEditText.java
com.oliveira.bubble.ChipsTextView.java
com.oliveira.bubble.CursorDrawable.java
com.oliveira.bubble.DefaultBubbles.java
com.oliveira.bubble.ILayoutCallback.java
com.oliveira.bubble.Linkify.java
com.oliveira.bubble.MultilineEditText.java
com.oliveira.bubble.Regex.java
com.oliveira.bubble.TappableSpan.java
com.oliveira.bubble.Utils.java