Android custom Control ViewGroup implementation Tag Cloud (d) _android

Source: Internet
Author: User

Objective:

The first few talked about the principle of custom control rendering Android custom Controls Basic Principles (i), Android custom control custom properties (ii), Android custom control of the custom Combination control (c), as the saying goes: "Good memory is not as bad as a pen, say not practice fake!!! ", as a learning slag is because did not follow this famous saying only reduced to this, so to the teachings, pay attention to the combination of theory and practice, today through the custom ViewGroup to implement the project used in the label cloud.

Requirement background:

The company needs to implement a knowledge point label showing that the length of each label is unknown, as shown in the following figure


Basic Drawing process:

Drawing principle here is no longer a general introduction to the drawing process
• Constructors Get custom properties
onmeasure () method to measure the size of a child control
onlayout () method, laying out the child controls

1.) Custom Properties

 <declare-styleable name= "Tagslayout" >
  <attr name= "Tagverticalspace" format= "Dimension"/>
  < attr name= "Taghorizontalspace" format= "Dimension"/>

2.) Gets the custom property value in the constructor function

private int childhorizontalspace;
 private int childverticalspace;

 Public Tagslayout (context, AttributeSet attrs) {
  Super (context, attrs);
  TypedArray Attrarray = context.obtainstyledattributes (Attrs, r.styleable.tagslayout);
  if (Attrarray!= null) {
   childhorizontalspace = attrarray.getdimensionpixelsize (r.styleable.tagslayout_ Taghorizontalspace, 0);
   Childverticalspace = attrarray.getdimensionpixelsize (r.styleable.tagslayout_tagverticalspace, 0);
   Attrarray.recycle ();
  }
 

3.) The Onmeasure function measures the size of the child control and then sets the current control size

 /** * Responsible for setting the measurement mode and size of the child control set its own width/height/@Override protected void onmeasure (int widthmeasurespec, int Heightmeasur) based on all child controls
  Espec) {super.onmeasure (Widthmeasurespec, Heightmeasurespec);
  Gets the measurement mode and size int sizewidth = measurespec.getsize (Widthmeasurespec) that its parent container sets for it;
  int sizeheight = measurespec.getsize (Heightmeasurespec);
  int modewidth = Measurespec.getmode (Widthmeasurespec);
  int modeheight = Measurespec.getmode (Heightmeasurespec);
  In the case of warp_content, record width and height int width = 0;
  int height = 0;
  /** * Record the width of each row, width continuously take the maximum width */int linewidth = 0;

  /** * The height of each row, add to Height */int lineheight = 0;
  int count = Getchildcount ();
  int left = Getpaddingleft ();
  int top = Getpaddingtop ();
   Iterate through each of the child elements for (int i = 0; i < count; i++) {View children = getchildat (i);
   if (child.getvisibility () = = GONE) continue;
   Measure each child's width and height measurechild (child, Widthmeasurespec, Heightmeasurespec); LP Marginlayoutparams LP = (marginlayoutparams) c with childHild.getlayoutparams ();
   The current child space actually occupies the width int childwidth = child.getmeasuredwidth () + lp.leftmargin + lp.rightmargin + childhorizontalspace;
   The current subspace actually occupies a height of int childheight = Child.getmeasuredheight () + lp.topmargin + lp.bottommargin + childverticalspace; /** * If the current child is added, the maximum width is exceeded, the current maximum width is given, class is added to the height and the new line is opened * * * (linewidth + childwidth > Sizewidth-getpad Dingleft ()-getpaddingright ()) {width = Math.max (linewidth, childwidth);//Max linewidth = childwidth;//re-open new
    Line, start recording//overlay current height, height + = lineheight;
    Open record the next line of height lineheight = childheight;  Child.settag (new Location, top + height, childwidth + left-childhorizontalspace, height + child.getmeasuredheight ()
   + top)); else {//otherwise the cumulative value linewidth,lineheight take the maximum height Child.settag (new Location (LineWidth + left, top + height, linewidth + CHILDW
    Idth-childhorizontalspace + Left, height + child.getmeasuredheight () + top);
    LineWidth + = Childwidth; Lineheight = Math. Max (Lineheight, childheight);
  } width = Math.max (width, linewidth) + getpaddingleft () + getpaddingright ();
  Height + = lineheight;
  Sizeheight + + getpaddingtop () + Getpaddingbottom ();
  Height + = getpaddingtop () + Getpaddingbottom (); Setmeasureddimension ((Modewidth = = measurespec.exactly)? sizewidth:width, (Modeheight = measurespec.exactly)? sizeHe
 Ight:height);

 }

To get the size of each child control by iterating through all child controls, and then by width overlay to determine whether to wrap, overlay the height of the control, and record the coordinates of the current child control, where the record coordinates refer to an internal class written by yourself Location.java

 /**
  * The coordinates of the record child control *
 /public class Location {public
  Location (int. left, int top, int right, int bottom) {
   This.left = left;
   This.top = top;
   This.right = right;
   This.bottom = bottom;
  }

  public int left;
  public int top;
  public int right;
  public int bottom;

 }

4.) OnLayout function to rearrange all child controls

 @Override
 protected void OnLayout (Boolean changed, int l, int t, int r, int b) {
  int count = Getchildcount (); 
   for (int i = 0; i < count; i++) {
   View child = Getchildat (i);
   if (child.getvisibility () = = GONE)
    continue;
   Location Location = (Location) child.gettag ();
   Child.layout (Location.left, Location.top, Location.right, Location.bottom);
  }
 

This is the direct traversal of all child controls to call the layout function of the child control to layout.  

How to use:
1). layout ask yourself in direct reference

<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android=
"http://schemas.android.com/apk/" Res/android "
 xmlns:lee=" Http://schemas.android.com/apk/res-auto "
 android:layout_width=" Match_parent "
 android:layout_height= "match_parent"
 android:orientation= "vertical" >

 < Com.whoislcj.views.TagsLayout
  android:id= "@+id/image_layout"
  android:layout_width= "Match_parent"
  android:layout_height= "wrap_content"
  android:layout_margin= "10DP"
  lee:taghorizontalspace= "10DP" "
  lee:tagverticalspace=" 10dp/>

</LinearLayout>

2). Code tagging

Tagslayout Imageviewgroup = (tagslayout) Findviewbyid (r.id.image_layout);
 Viewgroup.marginlayoutparams LP = new Viewgroup.marginlayoutparams (ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  String[] string={"from the day I wrote the code, I had no intention of writing code", "from the day I wrote the code", "I have no intention to write code", "No intention", "Write Code"};
  for (int i = 0; i < 5; i++) {
   TextView TextView = new TextView (this);
   Textview.settext (String[i]);
   Textview.settextcolor (color.white);
   Textview.setbackgroundresource (r.drawable.round_square_blue);
   Imageviewgroup.addview (TextView, LP);
  }

Concrete effect

3.) finally attach tagslayout full code

public class Tagslayout extends ViewGroup {private int childhorizontalspace;

 private int childverticalspace;
  Public Tagslayout (context, AttributeSet attrs) {Super (context, attrs);
  TypedArray Attrarray = context.obtainstyledattributes (Attrs, r.styleable.tagslayout); if (Attrarray!= null) {childhorizontalspace = Attrarray.getdimensionpixelsize (r.styleable.tagslayout_
   Taghorizontalspace, 0);
   Childverticalspace = attrarray.getdimensionpixelsize (r.styleable.tagslayout_tagverticalspace, 0);
  Attrarray.recycle (); /** * is responsible for setting the measurement mode and size of the child control set its own width/height/@Override protected void onmeasure (int widthmeasurespec, int heightm) based on all child controls
  Easurespec) {super.onmeasure (Widthmeasurespec, Heightmeasurespec);
  Gets the measurement mode and size int sizewidth = measurespec.getsize (Widthmeasurespec) that its parent container sets for it;
  int sizeheight = measurespec.getsize (Heightmeasurespec);
  int modewidth = Measurespec.getmode (Widthmeasurespec);
  int modeheight = Measurespec.getmode (Heightmeasurespec); IfIs warp_content case, record width and height int width = 0;
  int height = 0;
  /** * Record the width of each row, width continuously take the maximum width */int linewidth = 0;

  /** * The height of each row, add to Height */int lineheight = 0;
  int count = Getchildcount ();
  int left = Getpaddingleft ();
  int top = Getpaddingtop ();
   Iterate through each of the child elements for (int i = 0; i < count; i++) {View children = getchildat (i);
   if (child.getvisibility () = = GONE) continue;
   Measure each child's width and height measurechild (child, Widthmeasurespec, Heightmeasurespec);
   LP Marginlayoutparams LP = (marginlayoutparams) child.getlayoutparams () of the child;
   The current child space actually occupies the width int childwidth = child.getmeasuredwidth () + lp.leftmargin + lp.rightmargin + childhorizontalspace;
   The current subspace actually occupies a height of int childheight = Child.getmeasuredheight () + lp.topmargin + lp.bottommargin + childverticalspace; /** * If the current child is added, the maximum width is exceeded, the current maximum width is given, class is added to the height and the new line is opened * * * (linewidth + childwidth > Sizewidth-getpad Dingleft ()-getpaddingright ()) {width = Math.max (linewIdth, childwidth);/Take the largest linewidth = Childwidth;
    Reopen new line, start recording//overlay current height, height = lineheight;
    Open record the next line of height lineheight = childheight;  Child.settag (new Location, top + height, childwidth + left-childhorizontalspace, height + child.getmeasuredheight ()
   + top)); else {//otherwise the cumulative value linewidth,lineheight take the maximum height Child.settag (new Location (LineWidth + left, top + height, linewidth + CHILDW
    Idth-childhorizontalspace + Left, height + child.getmeasuredheight () + top);
    LineWidth + = Childwidth;
   Lineheight = Math.max (lineheight, childheight);
  } width = Math.max (width, linewidth) + getpaddingleft () + getpaddingright ();
  Height + = lineheight;
  Sizeheight + + getpaddingtop () + Getpaddingbottom ();
  Height + = getpaddingtop () + Getpaddingbottom (); Setmeasureddimension ((Modewidth = = measurespec.exactly)? sizewidth:width, (Modeheight = measurespec.exactly)? sizeHe
 Ight:height); @Override protected void OnLayout (Boolean changed, int l, int T, int r, int b) {int count = Getchildcount ();
   for (int i = 0; i < count; i++) {View child = Getchildat (i);
   if (child.getvisibility () = = GONE) continue;
   Location Location = (Location) child.gettag ();
  Child.layout (Location.left, Location.top, Location.right, Location.bottom); }/** * Record child control coordinates/public class Location {public Location (int left, int top, int right, int bottom) {thi
   S.left = left;
   This.top = top;
   This.right = right;
  This.bottom = bottom;
  public int left;
  public int top;
  public int right;

 public int bottom;
 }
}

Summarize:
so far as the simple custom controls have been introduced, the complex controls in the project are now less involved and then recorded later.

Related Article

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.