preface
The actual project needs to implement a popular search column, similar to the following: Since the text in the sub-view is variable, the number of sub-items that can be displayed in a line is also uncertain. Need to support wrapping and calculating positions.
\
\
�# Use the open source library SimpleFlowLayout
I wrote my own custom view, inherited from viewGroup, to implement it, hosted on github open source platform.
Name: SimpleFlowLayout address: https://github.com/vir56k/SimpleFlowLayout features: can keep adding more child view, the calculation of position, the word wrap. Similar to HTML div tags apply to: hot tagsCopy the code
Implementation approach
To implement a custom viewGroup, you need:
- Inherited from the ViewGroup
- Protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) this method is used to measure the width and height of your own (custom view)
- Protected void onLayout(Boolean changed, int L, int T, int r, int B) This method specifies how to place child views.
The implementation code
package zhangyf.vir56k.flowframelayout; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; /** * name: Android simple stream layout custom view ** ** features: can constantly add multiple sub-view, calculate position, automatic line wrap. * applies: Created by Zhangyunfei on 15/12/4. */ public class SimpleFlowLayout extends ViewGroup {public SimpleFlowLayout(Context context) { super(context); } public SimpleFlowLayout(Context context, AttributeSet attrs) { super(context, attrs); } public SimpleFlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMax = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMax = MeasureSpec.getSize(heightMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int widthNeed = 0; int heightNeed = 0; int x = 0; int y = 0; int currentLineHeight = 0; View child; for (int i = 0; i < getChildCount(); i++) { child = getChildAt(i); if (child.getVisibility() == View.GONE) { continue; } child.measure(widthMeasureSpec, heightMeasureSpec); MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); // Measure the width of the child view. Int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; // Use measureChildWithMargins on viewGroup to measure the width, Int childHeight = child.getMeasuredHeight() + lp.topmargin + lp.bottomMargin; measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; If (x + childWidth > widthMax) {// if (x + childWidth > widthMax) { currentLineHeight = 0; x = 0; } x += childWidth; currentLineHeight = Math.max(currentLineHeight, childHeight); widthNeed = Math.max(widthNeed, x); HeightNeed = math. Max (heightNeed, y + currentLineHeight); SetMeasuredDimension (widthMode == MeasureSpec.EXACTLY? widthMax : widthNeed, heightMode == MeasureSpec.EXACTLY ? heightMax : heightNeed); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int widthMax = getWidth(); int x, y; x = 0; y = 0; View child; int left = 0; int top = 0; int currentLineHeight = 0; for (int i = 0; i < getChildCount(); i++) { child = getChildAt(i); if (child.getVisibility() == View.GONE) { continue; } MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams(); int childWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; int childHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; If (x + childWidth > widthMax) {if (x + childWidth > widthMax) { x = 0; currentLineHeight = 0; } left = x + lp.leftMargin; top = y + lp.topMargin; Child.layout (left, top, left + child.getMeasuredWidth(), Top + Child.getMeasuredHeight ()); x += childWidth; currentLineHeight = Math.max(currentLineHeight, childHeight); } } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); }}Copy the code