About Android waterfall Flow control, has been in the lake, has been circulating for a long time, more than two years. There are also a lot of relevant learning resources on the Internet, which can be used for research and study. On GitHub, there are two of resources that can be worshipped by learners.
1.https://github.com/maurycyw/staggeredgridview This link has the picture loading function, but the function is relatively simple.
2.https://github.com/etsy/androidstaggeredgrid provides a powerful waterfall flow that allows you to customize the number of waterfall flow columns.
This blog, on the interpretation of the main source of Etsy. First Look at:
The definition of several variables in Staggeredgridview is first clarified:
private int mcolumncount; /* The number of columns of the default waterfall stream for the program, by default, defined by Grid_column_count in Integers.xml in the resource file */ private int mitemmargin; /* The margin of the default waterfall stream, defined by the app:item_margin= "8DP" in the layout file Activity_sgv.xml */ private int mcolumnwidth; /* Program waterfall Flow Column width variable */ private Boolean mneedsync; private int mcolumncountportrait = default_columns_portrait; /* Program Waterfall Stream Vertical Screen number */ private int mcolumncountlandscape = default_columns_landscape;/* program Waterfall Stream Horizontal Screen number */
For the waterfall flow, make clear the following several questions, also is the principle of thoroughly understand.
1. How do I calculate the width of each column when I have defined the number of columns in the waterfall stream?
2. How do I calculate the height of each column when I have defined the number of columns in the waterfall stream?
3. How is the Headerview of waterfall Flow added, and how is its height width determined?
4. How is the footerview of waterfall flow added , and how is its height width determined?
5. How does the selector of the highlighting and default backgrounds be implemented when clicking on the item of the waterfall stream?
I. How to calculate the width of each column when the number of columns in the waterfall stream is defined?
Enter the Staggeredgridactivity interface, waterfall flow UI effect has come out, mainly look at the Com.etsy.android.grid.StaggeredGridView Onmeasure method, determine the scale of each view.
@Override protected void onmeasure (final int widthmeasurespec, final int heightmeasurespec) { super.onmeasure ( Widthmeasurespec, Heightmeasurespec); if (mcolumncount <= 0) { Boolean islandscape = Islandscape (); Mcolumncount = Islandscape? mcolumncountlandscape:mcolumncountportrait; } Our column width is the width of the ListView //Minus it's padding//minus the total items margin /div IDed by the number of columns mcolumnwidth = Calculatecolumnwidth (Getmeasuredwidth ()); ... .... ... .... ... ....
variablesMcolumncount is from a resource fileIntegers.xml in Grid_column_count get, default is 2, functionCalculatecolumnwidth is used to calculate column widths, and its definition is simple and easy to understand.
private int calculatecolumnwidth (final int gridwidth) { final int listpadding = Getrowpaddingleft () + Getrowpaddingri Ght (); Return (Gridwidth-listpadding-mitemmargin * (Mcolumncount + 1))/Mcolumncount; }
that is, screen width-listpadding - Mitemmargindivide by the number of columns that is the width of the item. At this moment, the column widths are available. Continue to debug the code, because it is using Sampleadapter, each item in the waterfall stream calls the GetView method, which, like all adapter, imports the user-defined layout file from the layout file. The code is:Convertview = Mlayoutinflater.inflate (R.layout.list_item_sample, parent, false);
resource File the list_item_sample.xml is defined as follows:
<?xml version= "1.0" encoding= "Utf-8"? ><framelayout xmlns:android= "http://schemas.android.com/apk/ Res/android " android:orientation=" horizontal " android:id=" @+id/panel_content " android:layout_width = "Match_parent" android:layout_height= "match_parent" android:descendantfocusability= "blocksDescendants " android:background=" @drawable/recommend_app_bg "> < Com.etsy.android.grid.util.DynamicHeightTextView android:id= "@+id/txt_line1" android:layout_width= " Wrap_content " android:layout_height=" wrap_content " android:gravity=" center "/> <button android:id= "@+id/btn_go" android:layout_width= "wrap_content" android:layout_height= "Wrap_ Content " android:layout_gravity=" top|right " android:text=" Go "/></framelayout>
Here you need to knowDynamicheighttextviewdefinition of the. Throughout the adapter, the scale of the child item is determined by theDynamicheighttextviewto determine. The onmeasure in its class are as follows:
@Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) { if (Mheightratio > 0.0) { c8/>//Set the image views size int width = measurespec.getsize (widthmeasurespec); int height = (int) (width * mheightratio); Setmeasureddimension (width, height); } else { super.onmeasure (Widthmeasurespec, Heightmeasurespec); } }
Traversemheightratio aspect ratio, obtained from the setheightratio, after layers of code tracking, waterfall flow Neutron item height has been analyzed. The width of the sub-view is determined, first of all according to the screen size,and then according to the Sampleadaptergetrandomheightratio function, determines the height, height is the width of 1~1.5 times.
Private double Getrandomheightratio () { return (mrandom.nextdouble ()/2.0) + 1.0;//height would be 1.0-1.5 the WID Th }
Analysis to this point, you can answer the above questions 1 and 2.
two. How is the Headerview and footerview of the waterfall flow added, and how is the height width determined?
First Look at:
From Staggeredgridactivity, only a simple line of code, Mgridview.addheaderview (header), you can add head to the list. How does the sampleadapter of waterfall flow combine with Headview?
at Mgridview.setadapter (madapter), call the Setadapter method of Extendablelistview, Extendablelistview inherits from Abslistview. Extendablelistview. Java's Setadapter method is as follows:
@Override public void Setadapter (final listadapter adapter) { if (madapter! = null) { Madapter.unregisterdatasetobserver (Mobserver); } Use a wrapper list adapter if we have a header or footer if (mheaderviewinfos.size () > 0 | | mfooterviewinfos.siz E () > 0) { madapter = new Headerviewlistadapter (Mheaderviewinfos, Mfooterviewinfos, adapter); } else { Madapter = adapter; } ... ... ... ... ... ...
in theMheaderviewinfos orthe size of the Mfooterviewinfos is not 0 o'clock and constructs aHeaderviewlistadapter. It is defined as follows:
public class Headerviewlistadapter implements Wrapperlistadapter, filterable
as you can see from the definition, the object belongs to aListAdapter, since it is adapter, of course, do not escape a few important functions. GetCount (), Getitemviewtype (), GetView ().
public int GetCount () { if (madapter! = null) { return Getfooterscount () + getheaderscount () + Madapter.getcount () ; } else { return getfooterscount () + Getheaderscount (); } }
GetCountThat is, the adapter item number, when madapter! =null, return head and footer plusMadapter. GetCount. So. Head and footer are also associated with the regular waterfall flow item as an element of the adapter.
public int Getitemviewtype (int position) { int numheaders = Getheaderscount (); if (madapter! = null && position >= numheaders) { int adjposition = position-numheaders; int adaptercount = Madapter.getcount (); if (Adjposition < Adaptercount) { return madapter.getitemviewtype (adjposition); } } return adapterview.item_view_type_header_or_footer; }
The Getitemviewtype function is a more parametric position to determine whether the view type Id,view is from
getView函数中创建的。
该函数的意思是:head和footer的位置,返回AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER,普通的瀑布流item,将返回mAdapter.getItemViewType(adjPosition)。
接着就分析getView函数了。任何一个Adapter,都要重写getView
函数了,这是常识。
public View GetView (int position, View Convertview, ViewGroup parent) {//Header (negative positions would throw an Arrayindexo utofboundsexception) int numheaders = Getheaderscount (); if (position < numheaders) {return mheaderviewinfos.get (position). View; }//Adapter final int adjposition = position-numheaders; int adaptercount = 0; if (madapter! = null) {Adaptercount = Madapter.getcount (); if (Adjposition < Adaptercount) {return Madapter.getview (Adjposition, Convertview, parent); }}//Footer (off-limits positions would throw an arrayindexoutofboundsexception) return Mfooterview Infos.get (Adjposition-adaptercount). View; }
The meaning of the function is also easy to understand, and the header position will return Mheaderviewinfos.get (position). View;footer position, return Mfooterviewinfos.get (Adjposition- Adaptercount). View. The other location, the item view in the irregular GridView, returns Madapter.getview (Adjposition, Convertview, parent),MadapterObject will be called to the GetView method in the Sampleadapter.java.
At this point, we understand how the header and footer are added to the waterfall flow interface. Next, determine the height width of head and footer. Waterfall flow, from the UI effect, there are three types of type view, one is head, one is Staggeredgridview, the other is footer. Calculate the size of the sub-view, of course, pay attention to the Onmeasurechild function. The Onmeasurechild function in Staggeredgridview.java is defined as follows:
@Override protected void Onmeasurechild (final View child, final layoutparams layoutparams) { final int viewtype = Layoutparams.viewtype; final int position = layoutparams.position; if (ViewType = = Item_view_type_header_or_footer | | ViewType = = Item_view_type_ignore) { //For headers and weird ignored -super.onmeasurechild (Child, layoutparams); } else {... ... ... ... ...
As you can see, when viewtype = = Item_view_type_header_or_footer, call the parent class ExtendablelistviewOnmeasurechildmethod to calculate the scale of the head;ViewType! =Item_view_type_header_or_footer, go to the else process and calculate the dimensions according to int childwidthspec = Measurespec.makemeasurespec (Mcolumnwidth, measurespec.exactly).
three. how does the selector of the highlighting and default backgrounds be implemented when clicking on the item of the waterfall stream ?
This is studied in the next blog.
Android Waterfall Stream Staggeredgridview Learning Research