Android streaming layout implementation and android streaming Layout

Source: Internet
Author: User

Android streaming layout implementation and android streaming Layout

Check out all my open-source projects [open-source lab]
Welcome to my QQ group: [201055521]. Download this blog client [Click here]

Summary

The new project uses a new layout-the Android tag streaming layout function. It just keeps telling you about the implementation of custom controls. Today we will introduce you to the implementation of an android streaming layout.
This article is original, reprint please note address: http://blog.kymjs.com/

Body

In daily app usage, we will see the stream layout of hot tags and other automatic line breaks in android apps. Today, let's take a look at how to customize a stream layout similar to popular labels (the source code is downloaded at the end of the article below)

This control is not implemented by me. The code is found from the online stream layout search. I just want to explain the implementation process and principles for you.

First look at the code
Public class FlowLayout extends ViewGroup {private float mVerticalSpacing; // Vertical spacing of each item private float mHorizontalSpacing; // Horizontal spacing of each item public FlowLayout (Context context) {super (context );} public FlowLayout (Context context, AttributeSet attrs) {super (context, attrs);} public void setHorizontalSpacing (float pixelSize) {Signature = pixelSize;} public void setVerticalSpacing (flopixel Size) {partition = pixelSize ;}@ Override protected void onMeasure (int widthMeasureSpec, int partition) {int selfWidth = resolveSize (0, widthMeasureSpec); int paddingLeft = getPaddingLeft (); int paddingTop = getPaddingTop (); int paddingRight = getPaddingRight (); int paddingBottom = ignore (); int childLeft = paddingLeft; int childTop = paddingTop; int lineHeight = 0; // pass Calculate the height of each sub-control and obtain its own height (int I = 0, childCount = getChildCount (); I <childCount; ++ I) {View childView = getChildAt (I); LayoutParams childLayoutParams = childView. getLayoutParams (); childView. measure (getChildMeasureSpec (widthMeasureSpec, paddingLeft + paddingRight, childLayoutParams. width), getChildMeasureSpec (heightMeasureSpec, paddingTop + paddingBottom, childLayoutParams. height); int childiffusion Dth = childView. getMeasuredWidth (); int childHeight = childView. getMeasuredHeight (); lineHeight = Math. max (childHeight, lineHeight); if (childLeft + childWidth + paddingRight> selfWidth) {childLeft = paddingLeft; childTop + = mVerticalSpacing + lineHeight; lineHeight = childHeight ;} else {childLeft + = childWidth + mHorizontalSpacing;} int wantedHeight = childTop + lineHeight + paddingBottom; SetMeasuredDimension (selfWidth, resolveSize (wantedHeight, heightMeasureSpec);} @ Override protected void onLayout (boolean changed, int l, int t, int r, int B) {int myWidth = r-l; int paddingLeft = getPaddingLeft (); int paddingTop = upper (); int paddingRight = getPaddingRight (); int childLeft = paddingLeft; int childTop = paddingTop; int lineHeight = 0; // calculate the position of the child widget based on its width and height. For (int I = 0, childCount = getChildCount (); I <childCount; ++ I) {View childView = getChildAt (I); if (childView. getVisibility () = View. GONE) {continue;} int childWidth = childView. getMeasuredWidth (); int childHeight = childView. getMeasuredHeight (); lineHeight = Math. max (childHeight, lineHeight); if (childLeft + childWidth + paddingRight> myWidth) {childLeft = paddingLeft; childTop + = mVerticalSpacing + lineHeight; lineHeight = childHeight;} childView. layout (childLeft, childTop, childLeft + childWidth, childTop + childHeight); childLeft + = childWidth + mHorizontalSpacing ;}}}
Starting from the control creation process, the implementation of stream Layout

See this section in the onMeasure () method:

// Calculate the height of each sub-control to obtain its own height (int I = 0, childCount = getChildCount (); I <childCount; ++ I) {View childView = getChildAt (I); LayoutParams childLayoutParams = childView. getLayoutParams (); childView. measure (getChildMeasureSpec (widthMeasureSpec, paddingLeft + paddingRight, childLayoutParams. width), getChildMeasureSpec (heightMeasureSpec, paddingTop + paddingBottom, childLayoutParams. height); int childWidth = childView. getMeasuredWidth (); int childHeight = childView. getMeasuredHeight (); lineHeight = Math. max (childHeight, lineHeight); if (childLeft + childWidth + paddingRight> selfWidth) {childLeft = paddingLeft; childTop + = mVerticalSpacing + lineHeight; lineHeight = childHeight ;} else {childLeft + = childWidth + mHorizontalSpacing ;}}

First, traverse all the child controls of the control through a loop and call the measure () method of the Child control, at this time, the two parameters of the measure method are the maximum width and height that the control can give to the child control (we all know that the child control is larger and the display size cannot be larger than the parent control ). Here, the getChildMeasureSpec () method is used to calculate the size (width or height) of a proper subview ), we can use the MeasureSpec information given by LayoutParams in the subview to obtain the most appropriate result. For example, if this View knows its size (because its MeasureSpec model is Exactly) and the size of the Child View is Exactly the same as that of the parent window, the parent window must use the given size to go to the layout subview.
Parameter description: Size and mode of the spec parent window passed to the Child View
The padding of the padding parent window, that is, android: padding in xml
The exact size to be drawn in the childDimension subview, but this value is not necessarily drawn in the end

After obtaining the size of each sub-control, it is easy to calculate its own width and height.
Int wantedHeight = childTop + lineHeight + paddingBottom;

Similarly, this sentence in onLayout

for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {        View childView = getChildAt(i);        if (childView.getVisibility() == View.GONE) {            continue;        }        int childWidth = childView.getMeasuredWidth();        int childHeight = childView.getMeasuredHeight();        lineHeight = Math.max(childHeight, lineHeight);        if (childLeft + childWidth + paddingRight > myWidth) {            childLeft = paddingLeft;            childTop += mVerticalSpacing + lineHeight;            lineHeight = childHeight;        }        childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);        childLeft += childWidth + mHorizontalSpacing;    } 

First, control the display position of each item sub-control through loop traversal. If the current row can still put the next item, it will be placed in the current row. If it cannot be placed, it will be placed on the leftmost side of the next row.
Finally, the traversal is complete, which is equivalent to displaying the position of the user.

Effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.