Android Custom ViewGroup to implement label floating effect _android

Source: Internet
Author: User

In front of learning some of Hongyang's custom view articles, see the custom ViewGroup implementation floating tag, initial look at his ideas as well as the combination of his own ideas to complete his own floating label custom ViewGroup. Currently implemented can dynamically add tags, clickable. The effect chart is as follows:

1. Train of Thought
First of all, we measure the width and height of viewgroup in the Onmeasure method, and focus on how to measure the size of the ViewGroup when our custom set is wrap_content. When our custom ViewGroup is set to wrap_content, we need to let the child view measure itself first, and when the child view is finished, Then, the Getmeasuredwidth and Getmeasureheight methods of the child view are used to obtain the width and height of the child view. Each time you measure a child view, you need to determine whether the current row can hold the child view if you add it, and if not, you need to open a new line and record the maximum height of the current row.
In the OnLayout method, the core character is the placement of each child view, which means that for each child view in the ViewGroup, the two points above the box model, namely the upper left corner and the lower right corner, point (L,t) and Point (R,b), are identified, two points The position of the child view is also determined.

2. Realize
The basic idea has to try to implement, the code is as follows:
Custom ViewGroup:

/** * Flow Label (dynamic, add tags dynamically according to incoming data) * * public class Dynamictagflowlayout extends ViewGroup {private list<string> MT
 
 AGS = new arraylist<string> ();
 Public Dynamictagflowlayout (context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);
 Public Dynamictagflowlayout (context, AttributeSet attrs) {Super (context, attrs);
 Public Dynamictagflowlayout {Super (context); @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int widthmode = Measurespec.getmo
 De (WIDTHMEASURESPEC);
 int widthsize = measurespec.getsize (Widthmeasurespec);
 int heightmode = Measurespec.getmode (Heightmeasurespec);
 
 int heightsize = measurespec.getsize (Heightmeasurespec);
 Total height of current viewgroup int totalheight= 0;
 
 Maximum width int maxlinewidth = 0 in all rows;
 Maximum height of the current row int linemaxheight = 0;
 
 The total width of the current line int currentlinewidth = 0;
 The width of each childview is int childviewwidthspace = 0; The height of each childview is int childvieWheightspace = 0;
 int count = Getchildcount ();
 
 Marginlayoutparams Layoutparams;
  
  for (int i = 0; i < count; i++) {View child = Getchildat (i); if (child.getvisibility ()!= view.gone) {//Only when this view is able to be displayed, measure each view to get the width and height measurechild of the child view,
  
  Widthmeasurespec, Heightmeasurespec);
  
  Layoutparams = (marginlayoutparams) child.getlayoutparams ();
  Childviewwidthspace = child.getmeasuredwidth () + Layoutparams.leftmargin + layoutparams.rightmargin;
  
  Childviewheightspace = child.getmeasuredheight () + Layoutparams.topmargin + layoutparams.bottommargin; if (Currentlinewidth + childviewwidthspace > Widthsize) {//means that if the current row is added to this view, it will exceed the total specified width, and another line is required totalheight =
   Linemaxheight;
   if (Maxlinewidth < currentlinewidth) {//If the longest width of the row has changed, update the saved longest width maxlinewidth = currentlinewidth;
  Currentlinewidth = childviewwidthspace;//Another row, you need to reset the current line width linemaxheight = childviewheightspace;
   }else{//indicates that the current row can continue to add child elements currentlinewidth + = Childviewwidthspace;if (Linemaxheight < childviewheightspace) {linemaxheight = Childviewheightspace; }}} setmeasureddimension (Widthmode = = measurespec.exactly? widthsize:maxlinewidth, Heightmode = = MeasureSpe C.exactly?
 
 Heightsize:totalheight);
 @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {//is currently the first row of int currentline = 1;
 
 Store the maximum height of each row list<integer> linemaxheightlist = new arraylist<integer> ();
 The width of each childview is int childviewwidthspace = 0;
 
 Each childview occupies a height of int childviewheightspace = 0;
 Maximum height of the current row int linemaxheight = 0;
 
 The total width of the current line int currentlinewidth = 0;
 int count = Getchildcount ();
 
 Marginlayoutparams Layoutparams;
  for (int i = 0; i < count; i++) {int cl= 0, ct = 0, CR = 0, cb = 0;
  View child = Getchildat (i); if (child.getvisibility ()!= view.gone) {//only measure Layoutparams = (marginlayoutparams) When this View can be displayed Child.getlayoutpar
  AMS (); Childviewwidthspace = child.getmeasuredwidth () + LayoutparAms.leftmargin + layoutparams.rightmargin;
  
  Childviewheightspace = child.getmeasuredheight () + Layoutparams.topmargin + layoutparams.bottommargin;
  
  System.out.println ("getwidth ()---->" +getwidth ());
   if (Currentlinewidth + childviewwidthspace > getwidth ()) {//means that if the current row is added to this view, it will exceed the overall specified width and need a different line
   Linemaxheightlist.add (linemaxheight) The maximum height of this row is added to the collection//new row, resetting some parameters currentline++;
   Currentlinewidth = Childviewwidthspace;
   
   Linemaxheight = Childviewheightspace;
   CL = Layoutparams.leftmargin;
   if (CurrentLine > 1) {for (int j = 0; J < CurrentLine-1; J +) {ct = Linemaxheightlist.get (j);
   CT + = Layoutparams.topmargin;
   }else{ct = layoutparams.topmargin;
   }else{//indicates that the current row can continue to add child elements cl = currentlinewidth + layoutparams.leftmargin;
   if (CurrentLine > 1) {for (int j = 0; J < CurrentLine-1; J +) {ct = Linemaxheightlist.get (j);
   CT + = Layoutparams.topmargin;
   }else{ct = layoutparams.topmargin;
   }Currentlinewidth + = Childviewwidthspace;
   if (Linemaxheight < childviewheightspace) {linemaxheight = Childviewheightspace;
  } CR = Cl + child.getmeasuredwidth ();
  
  CB = CT + child.getmeasuredheight ();
  
  Child.layout (CL, CT, CR, CB); @Override public layoutparams generatelayoutparams (AttributeSet attrs) {return new Marginlayoutparams (Getcon
 Text (), attrs);
  public void Settags (list<string> tags) {if (tags!= null) {mtags.clear ();
  Mtags.addall (tags);
  for (int i = 0; i < mtags.size (); i++) {TextView TV = new TextView (GetContext ());
  Marginlayoutparams LP = new Marginlayoutparams (marginlayoutparams.wrap_content, marginlayoutparams.wrap_content);
Lp.setmargins (15, 15, 15, 15);
Lp.width = marginlayoutparams.wrap_content;
  Lp.height = marginlayoutparams.wrap_content;
  TV.SETLAYOUTPARAMS (LP);
  Tv.setbackgroundresource (R.DRAWABLE.TV_BG);
   * * setpadding must be used after setbackgroundresource to be effective!!! * Http://stackoverflow.com/questions/18327498/setting-padding-for-textview-not-working * * tv.setpadding (15, 15, 15, 15);
  
  Tv.settextcolor (Color.White);
  
  Tv.settext (Mtags.get (i)); Tv.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {if (listener!= null) {L
   Istener.onclick (v);
  
  }
   }
  });
  AddView (TV);
 } requestlayout ();
 } private Ontagitemclicklistener Listener;
 public interface ontagitemclicklistener{public void OnClick (View v);
 public void Setontagitemclicklistener (Ontagitemclicklistener l) {listener = l;
 }

}

Mainactivity:

public class Mainactivity extends activity {private dynamictagflowlayout dynamictagflowlayout;

 list<string> tags = new arraylist<string> ();
 @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
 
 Setcontentview (r.layout.activity_dynamic_tagflowlayout);
 Dynamictagflowlayout = (dynamictagflowlayout) Findviewbyid (R.id.dynamic_tag);
  Dynamictagflowlayout.setontagitemclicklistener (New Ontagitemclicklistener () {@Override public void OnClick (View v) {
  TextView TV = (TextView) v;
  Toast.maketext (Mainactivity.this, Tv.gettext (). toString (), Toast.length_short). Show ();
 
 }
 });
 InitData ();
 Dynamictagflowlayout.settags (tags); private void InitData () {tags.add, Hello!
 ");
 Tags.add ("Android Development");
 Tags.add ("Hot News"); Tags.add ("Hot water into the dormitory!")
 ");
 Tags.add ("I Love You");
 Tags.add ("Chengdu sister");
 Tags.add ("Xinyu sister");
 Tags.add ("Fairy Lake");
 Tags.add ("Innovation Factory");
 Tags.add ("Hatchery Garden");
 Tags.add ("Shenzhou 100 Launch");
 Tags.add ("poisonous vaccine"); Tags.add ("Top you Yang Goyang elder brother");
 Tags.add ("Hello World");
 Tags.add ("wandering ants");
 Tags.add ("wandering ants");
 Tags.add ("wandering ants");
 Tags.add ("wandering ants");
 Tags.add ("wandering ants");
 Tags.add ("wandering ants");

 }

}

SOURCE Download: Android Streaming tags can dynamically add FlowLayout

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.