Simple message Flow UI for the ListView nesting GridView in Android (addressing the wide-height problem)

Source: Internet
Author: User

In a recent project, a message flow similar to Sina Weibo is needed, with each text and nine picture, so this involves a ListView or ScrollView nested gridview problem. The height of the GridView problem on the Internet is easy to find the answer, that is, overwrite the Onmeasure method, and then set the height of the measurespec. However, the width of the problem does not have any information, the width of the problem is such as the GridView column number is 3, so even if there is only one picture, the width of the GridView is Match_parent, Click events in the ListView that cause the user to click outside the picture range but within the GridView range cannot be captured.

:


The problem arises as above, when there is only one icon when the width of the GridView (gray area) is also match_parent, this time clicking the GridView area is the ListView is not responsive, However, if the background color of the GridView is consistent with the background of the ListView, the user is not able to see the width of the GridView, and when the user clicks outside the image, the possible action is to enter the detail page of the message, but since the GridView is Match_parent, So the ListView doesn't get a click event at all, so the experience is bad. The effect we need is this:


that is, the size of the GridView can include the size of the picture, so that when the background color of the GridView is the default, users click outside the image of the area is clicked on the ListView item.

Let's see how to solve this problem, first of all, the layout is not talk about, mainly talk about the problem of the width of the GridView. To solve the height problem of the GridView, you need to overwrite the Onmeasure method of the GridView, the code is as follows:

public class    Mgridview extends GridView {public Boolean hasscrollbar = true;    /** * @param context */public Mgridview (context context) {This (context, NULL);    } public Mgridview (context context, AttributeSet Attrs) {Super (context, attrs, 0);    } public Mgridview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle); } @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int expandspec = Heightme        Asurespec; if (hasscrollbar) {expandspec = Measurespec.makemeasurespec (integer.max_value >> 2, M            Easurespec.at_most); Super.onmeasure (Widthmeasurespec, expandspec);//note here The meaning is to directly measure the height of the GridView} else {super.onmeasure (WI        Dthmeasurespec, Heightmeasurespec); }    }}
      In the Onmeasure method, because Hasscrollbase is true, we notice the commented branch in the code. This is actually the height of the GridView at the time of onmeasure, not just the height of several of the view. Without this step, the height of the GridView will not be fully displayed. Calculates the height of the GridView so that it does not need to slide up and down to show the other item, because the problem is that the GridView is nested in the ScrollView or the component containing the ScrollView, causing the conflict.

To solve the problem of width, the idea is to manually calculate the number of images per gridview in the GetView method of the ListView, if the number of images is less than the number of columns per row of the GridView, manually calculate the required width for each child view, Then the width of the GridView = child number * The width of each child view. To avoid repeated calculations, we cache the results of the calculations. The calculation code is as follows:

/** * @author mrsimple */public final class Gridviewutils {/** * storage width */static Sparseintarray Mgvwidth = n    EW Sparseintarray (); /** * Calculates the height of the GridView * * @param gridview to calculate the GridView */public static void Updategridviewlayoutparams (        Mgridview gridView, int maxcolumn) {int childs = Gridview.getadapter (). GetCount ();            if (Childs > 0) {int columns = Childs < Maxcolumn? Childs% Maxcolumn:maxcolumn;            Gridview.setnumcolumns (columns);            int width = 0;            int cachewidth = mgvwidth.get (columns);            if (cachewidth! = 0) {width = cachewidth;                     else {//calculates the width of each row of the GridView, and calculates the width of all item if item is less than 3; Otherwise, only 3 child widths are computed, so a row has a maximum of 3 child. (Here we take 3 as an example) int rowcounts = Childs < Maxcolumn?                Childs:maxcolumn; for (int i = 0; i < rowcounts; i++) {View Childview = Gridview.getadapter (). GetView (i, NULL, GRIDVI ew;                    Childview.measure (0, 0);                width + = childview.getmeasuredwidth ();            }} viewgroup.layoutparams params = Gridview.getlayoutparams ();            Params.width = width;            Gridview.setlayoutparams (params);            if (mgvwidth.get (columns) = = 0) {mgvwidth.append (columns, width); }        }    }

The GetView method for the ListView is as follows:

@Override public View getView (int position, view Convertview, ViewGroup parent) {Viewholder viewholder = null;            if (Convertview = = null) {Convertview = Minflater.inflate (R.layout.listview_item, parent, false);            Viewholder = new Viewholder ();            Viewholder.mgridview = (Mgridview) Convertview.findviewbyid (R.id.my_gridview);            Viewholder.mtextview = (TextView) Convertview.findviewbyid (R.ID.MY_TV);        Convertview.settag (Viewholder);        } else {Viewholder = (Viewholder) convertview.gettag ();        } final ListViewItem item = getItem (position);        Set the adapter ViewHolder.mGridView.setAdapter of the GridView (New Gridviewadapter (Mcontext, item.mimages));        Calculates the GridView width, setting the default to NumColumns to 3.        Gridviewutils.updategridviewlayoutparams (Viewholder.mgridview, 3);        ViewHolder.mTextView.setText (Item.mtext);    return convertview; }

In this way, we solve the problem of the width and height of the message flow.


Demo Address: Punch here ~

Simple message Flow UI for the ListView nesting GridView in Android (addressing the wide-height problem)

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.