First, flow-style layout effect
Second, the engineering structure
Iii. new Project, custom Groupview (flow layout)
PackageCom.yuanlei.flowlayoutdemo;ImportAndroid.content.Context;ImportAndroid.util.AttributeSet;ImportAndroid.util.Log;ImportAndroid.view.View;ImportAndroid.view.ViewGroup;Importjava.util.ArrayList;Importjava.util.List;/*** Created by Mr. Yuan on 2017/2/17.*/ Public classFlowLayoutextendsViewGroup { PublicFlowLayout (Context context) {//constructor method for calling two parameters This(Context,NULL); } PublicFlowLayout (Context context, AttributeSet attrs) {//constructor method for calling three parameters This(context, Attrs, 0); } PublicFlowLayout (context context, AttributeSet attrs,intdefstyleattr) { Super(context, attrs, defstyleattr); } @Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec) { intSizewidth = Measurespec.getsize (Widthmeasurespec);//Group Width intModewidth = Measurespec.getmode (Widthmeasurespec);//group width measurement mode intSizeheight = Measurespec.getsize (Heightmeasurespec);//Group Height intModeheight = Measurespec.getmode (Heightmeasurespec);//group Height measurement mode//Wrap_content in case of wide height intwidth = 0; intHeight = 0; //record the total width and height of each row intLineWidth = 0; intLineheight = 0; //get the number of internal elements intCcount =Getchildcount (); for(inti = 0; i < ccount; i++) {View child=Getchildat (i); //measuring the width and height of sub-viewMeasurechild (Child, Widthmeasurespec, Heightmeasurespec); //get the layoutparams of the child viewMarginlayoutparams LP =(Marginlayoutparams) child.getlayoutparams (); //the width occupied by the child view intChildwidth = child.getmeasuredwidth () + Lp.leftmargin +Lp.rightmargin; //the height occupied by the child view intChildheight = child.getmeasuredheight () + Lp.topmargin +Lp.bottommargin; //When changing lines if(LineWidth + childwidth > Sizewidth-getpaddingleft ()-getpaddingright ()) {//(current first line width) + (one child view width) > (width of control)//compare to get the maximum line widthwidth =Math.max (width, linewidth); //Reset linewidthLineWidth =Childwidth; //Record Row HeightHeight + =lineheight; Lineheight=Childheight; } Else{//do not change lines//Overlay Row WidthLineWidth + =Childwidth; //get the maximum height of the current rowLineheight =Math.max (Lineheight, childheight); } //Last child control if(i = = CCount-1) {width=Math.max (linewidth, width); Height+=lineheight; }} log.d ("TAG", "sizewidth=" +sizewidth); LOG.D ("TAG", "sizeheight=" +sizeheight); Setmeasureddimension (Modewidth= = measurespec.exactly? Sizewidth:width + getpaddingleft () +getpaddingright (), Modeheight= = measurespec.exactly? Sizeheight:height + getpaddingtop () +Getpaddingbottom ()); } //Store All view (note: one row of storage) PrivateList<list<view>> mallviews =NewArraylist<>(); //the height of each row PrivateList<integer> mlineheight =NewArraylist<>(); @Overrideprotected voidOnLayout (BooleanChangedintLintTintRintb) {mallviews.clear (); Mlineheight.clear (); //width of current viewgroup intwidth =getwidth (); intLineWidth = 0; intLineheight = 0; List<View> lineviews =NewArraylist<>(); intCcount =Getchildcount (); for(inti = 0; i < ccount; i++) {View child=Getchildat (i); Marginlayoutparams LP=(Marginlayoutparams) child.getlayoutparams (); intChildwidth =child.getmeasuredwidth (); intChildheight =child.getmeasuredheight (); //If a line break is required if(childwidth + linewidth + lp.leftmargin + lp.rightmargin >width-Getpaddingleft ()-getpaddingright ()) { //Record LineheightMlineheight.add (lineheight); //Records All child view of the current lineMallviews.add (lineviews); //Reset Our line width and row heightsLineWidth = 0; Lineheight= childheight + Lp.topmargin +Lp.bottommargin; //Reset Our collectionLineviews =NewArraylist<>(); } linewidth+ = Childwidth + Lp.leftmargin +Lp.rightmargin; Lineheight= Math.max (lineheight, childheight + Lp.topmargin +lp.bottommargin); Lineviews.add (child); }//For Loop End//process the last lineMlineheight.add (lineheight); Mallviews.add (lineviews); //set the location of a child view intleft =Getpaddingleft (); inttop =Getpaddingtop (); //Number of rows intLineNum =mallviews.size (); for(inti = 0; i < linenum; i++) { //all view of the current line (overall per row)Lineviews =Mallviews.get (i); Lineheight=Mlineheight.get (i); //traverse all view of each row (child view inside each row) for(intj = 0; J < Lineviews.size (); J + +) {View child=Lineviews.get (j); //interpreting the state of child if(child.getvisibility () = =view.gone) {Continue; } marginlayoutparams LP=(Marginlayoutparams) child.getlayoutparams (); //Child 's Left,right,top,bottom intLC = left +Lp.leftmargin; intRC = LC +child.getmeasuredwidth (); intTC = top +Lp.topmargin; intBC = TC +child.getmeasuredheight (); //lay out a child viewChild.layout (LC, TC, RC, BC); //in each row of the sub view, only need to change the left position, the height of the sameLeft + = Child.getmeasuredwidth () + Lp.leftmargin +Lp.rightmargin; } Left=Getpaddingleft (); Top+=lineheight; } } /*** Layoutparams corresponding to the current ViewGroup*/@Override Publiclayoutparams generatelayoutparams (AttributeSet attrs) {return NewMarginlayoutparams (GetContext (), attrs); }}
FlowLayout
Shape of a neutron view (TextView) with Flow layout
<?xml version= "1.0" encoding= "Utf-8"? ><shape xmlns:android= "Http://schemas.android.com/apk/res/android" > <solid android:color= "#ffffff"/> <corners android:radius= "30DP"/> <padding android:bottom= "2DP" android:left= "10DP" android:right= "10DP" Android:top= "2DP"/></shape>
TV_BG
V. Sub-view (TextView) in streaming layout
<?xml version= "1.0" encoding= "Utf-8"? ><textview xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" Wrap_content " android:layout_height=" Wrap_content " Android:layout_margin= "5DP" android:background= "@drawable/tv_bg" android: Text= "Hello Word" android:textcolor= "#5bc4ed"/>
MY_TV
Vi. using a flow-style layout
<?xml version= "1.0" encoding= "Utf-8"? ><textview xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" Wrap_content " android:layout_height=" Wrap_content " Android:layout_margin= "5DP" android:background= "@drawable/tv_bg" android: Text= "Hello Word" android:textcolor= "#5bc4ed"/>
mainactivity
Layout file:
<?xml version= "1.0" encoding= "Utf-8"? ><relativelayout xmlns:android= "http://schemas.android.com/apk/res/ Android " android:layout_width=" Match_parent " android:layout_height=" Match_parent " > <com.yuanlei.flowlayoutdemo.FlowLayout android:id= "@+id/my_fl_main" android: Layout_width= "Match_parent" android:layout_height= "Wrap_content" android: Background= "#33000000"/></relativelayout>
Activity_main
Vii. Points of knowledge
1. Custom ViewGroup:
1.onMeasure: Measure sub-view width and height, set your own width and height
2.onLayout: Set the location of the child view
Onmeasure: Sets the measurement mode and measurement values for sub-view according to the layout file of the child view
Measurement = measurement mode + measured value
Measuring mode: 3 kinds
1.EXACTLY:100DP (direct setting), match_parent
2.at_most:wrap_content
3.UNSPCIIFIED: Child controls how big you want (rarely seen)
Android Streaming layout