Android Custom ViewGroup (choose photos or take pictures)

Source: Internet
Author: User

Teach you to take care of Android custom ViewGroup http://www.jianshu.com/p/138b98095778 words 1794 read 7030 comments 8 likes 37 Previous we introduced the knowledge of custom view in Android, and implemented a custom view like the Google Rainbow Progress bar, and today we'll learn more about customizing a viewgroup. ViewGroup we know that ViewGroup is the container class of view, we often use the linearlayout,relativelayout and so on are ViewGroup subclasses, because ViewGroup has a lot of sub-view, So its entire drawing process is a bit more complicated than the view, but it's still three steps Measure,layout,draw, as we explained at once. Measuremeasure process or measure the size of viewgroup, if Layout_widht and Layout_height is match_parent or specific XXXDP, it is simple answer, Call the Setmeasureddimension () method directly, set the width of the viewgroup, if it is wrap_content, it is more troublesome, we need to traverse all sub-view, and then each sub-view to measure, Then, according to the arrangement rules of sub-view, calculate the size of the final viewgroup.  @Overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int childCount = This.getchildcount ();      for (int i = 0; i < ChildCount; i++) {View child = This.getchildat (i);      This.measurechild (Child, Widthmeasurespec, Heightmeasurespec);      int cw = Child.getmeasuredwidth ();  int ch = child.getmeasuredheight (); }} You may need to resemble the above code, where the Getchildcount () method, which returns the number of child view, the Measurechild () method, invokes the measurement method of the child view. In the previous article of layout, we mentioned a little bit about, the layout process is actually aligned to the position of the pair view, and the OnLayout method gives me a chance to customize the sub-view arrangement according to the rules we want. @Overrideprotected void OnLayout (boolean arg0, int arg1, int arg2, int arg3, int arg4) {int childCount = This.getchildco  UNT ();      for (int i = 0; i < ChildCount; i++) {View child = This.getchildat (i);      Layoutparams lparams = (layoutparams) child.getlayoutparams ();  Child.layout (Lparams.left, lparams.top, Lparams.left + childwidth, lparams.top + childheight); You may also need to resemble the above code, where the Child.layout (Left,top,right,bottom) method can be set to the position of the child view, the meaning of the four parameters should be clear through the variable name. Drawviewgroup in the draw stage, in fact, according to the order of the sub-class, call the OnDraw method of the subclass, because we are only the view of the container, itself generally do not need to draw additional decorations, so often in the OnDraw method inside, You only need to call ViewGroup's OnDraw default implementation method. Layoutparamsviewgroup also has a very important knowledge layoutparams,layoutparams stores some parameter information when a child view is added to the ViewGroup, when inheriting the ViewGroup class, In general, a new Layoutparams class is also required Just like the Linearlayout.layoutparams,relativelayout.layoutparams class we are familiar with in the SDK, so you can do this, in the ViewGroup subclass you define, create a new Layoutparams class that inherits from the VIEWGR Oup. Layoutparams. public static class Layoutparams extends VIEWGROUP.LAYOUTPARams {public int left = 0;  public int top = 0;  Public Layoutparams (Context arg0, AttributeSet arg1) {super (arg0, arg1);  } public layoutparams (int arg0, int arg1) {super (arg0, arg1);  } public Layoutparams (Android.view.ViewGroup.LayoutParams arg0) {super (arg0); So now that the new Layoutparams class has been introduced, how can we customize the ViewGroup to use our custom Layoutparams class to add sub-view, ViewGroup also provides the following methods for us to rewrite, We rewrite the Layoutparams object to return our custom. @Overridepublic android.view.ViewGroup.LayoutParams generatelayoutparams (AttributeSet attrs) {return new Ninephoto View.layoutparams (GetContext (), attrs);} @Overrideprotected android.view.ViewGroup.LayoutParams Generatedefaultlayoutparams () {return new Layoutparams ( Layoutparams.wrap_content, layoutparams.wrap_content);} @Overrideprotected android.view.ViewGroup.LayoutParams generatelayoutparams (Android.view.ViewGroup.LayoutParams p {return new Layoutparams (p);} @Overrideprotected boolean checklayoutparams (Android.view.ViewGroup.LayoutParams p) {return p instanceof ninephotoview.layoutparams;} Examples we still do an example to illustrate, we do a similar circle of friends today to save the image to send the control, click on the + number picture, you can always add pictures, up to 9 photos. So is 4 a row, we here is 3 a row, because the general standard is three a row, these are the details do not care (also secretly tell everyone, the realization is to use Tablelayout,-.-). Friends Circle send picture friend circle send picture public class Ninephotoview extends ViewGroup {public static final int max_photo_number = 9;private int[] Con Stimageids = {r.drawable.girl_0, r.drawable.girl_1, r.drawable.girl_2, R.drawable.girl_3, R.drawable.girl_4, R. Drawable.girl_5, R.drawable.girl_6, r.drawable.girl_7, r.drawable.girl_8};//horizontal space among children Viewsin T hspace = utils.dptopx (Ten, Getresources ());//Vertical space among children viewsint vspace = utils.dptopx (GETRESOURC ES ());//Every Child view width and height.int childwidth = 0;int childheight = 0;//Store images res idarraylist<integ er> mimageresarraylist = new Arraylist<integer> (9);p rivate View addphotoview;public Ninephotoview (Context Context) {super (context);} Public Ninephotoview (context context, AttributeSet Attrs) {This (ContexT, attrs, 0);}  Public Ninephotoview (context context, AttributeSet attrs, int defstyle) {Super (context, attrs, Defstyle);  TypedArray t = context.obtainstyledattributes (attrs, R.styleable.ninephotoview, 0, 0);  hspace = T.getdimensionpixelsize (R.styleable.ninephotoview_ninephoto_hspace, hspace);  vspace = T.getdimensionpixelsize (R.styleable.ninephotoview_ninephoto_vspace, vspace);  T.recycle ();  Addphotoview = new View (context);  AddView (Addphotoview); Mimageresarraylist.add (New Integer ());} So far, all the same as the previous one said, in addition to take photos and select pictures from the album is not the focus of our article, so we have to hard code the picture into the codes (all beautiful ...) ), ViewGroup initialized when we added a + sign button to give the user click to add a new image. measure@overrideprotected void onmeasure (int widthmeasurespec, int heightmeasurespec) {int rw = measurespec.getsize (wid  THMEASURESPEC);  int RH = Measurespec.getsize (HEIGHTMEASURESPEC);  Childwidth = (rw-2 * hspace)/3;  Childheight = Childwidth;  int childCount = This.getchildcount (); for (int i = 0; i < ChildCount; i++) {View child = This.getchildat (i);     This.measurechild (Child, Widthmeasurespec, Heightmeasurespec);      Layoutparams lparams = (layoutparams) child.getlayoutparams ();      Lparams.left = (i% 3) * (Childwidth + hspace);  Lparams.top = (I/3) * (Childwidth + vspace);  } int vw = RW;  int VH = RH;  if (ChildCount < 3) {VW = ChildCount * (childwidth + hspace);  } VH = ((ChildCount + 3)/3) * (Childwidth + vspace); Setmeasureddimension (VW, VH);} Our sub-view is three rows in a row, and all are squares, so we have a good way to get all the sub-view positions in the loop above, and note that the upper-left corner of the top of the handle view is stored in our custom layoutparams and top two fields. The layout stage is used, and finally we calculate the width of the entire viewgroup, calling setmeasureddimension settings. layout@overrideprotected void OnLayout (boolean arg0, int arg1, int arg2, int arg3, int arg4) {int childCount = This.getc  Hildcount ();      for (int i = 0; i < ChildCount; i++) {View child = This.getchildat (i);      Layoutparams lparams = (layoutparams) child.getlayoutparams ();      Child.layout (Lparams.left, lparams.top, Lparams.left + childwidth, lparams.top + childheight); if (i = = Mimageresarraylist.size ()-1 && mimageresarraylist.size ()! = Max_photo_number) {Child.setbackgroun          Dresource (R.drawable.add_photo);                   Child.setonclicklistener (New View.onclicklistener () {@Override public void OnClick (View arg0) {              Addphotobtnclick ();      }          });          }else {Child.setbackgroundresource (constimageids[i]);      Child.setonclicklistener (NULL); }}}public void Addphoto () {if (Mimageresarraylist.size () < Max_photo_number) {View NewChild = new View (Getcon      Text ());      AddView (NewChild);      Mimageresarraylist.add (New Integer ());      Requestlayout ();  Invalidate ();  }}public void Addphotobtnclick () {final charsequence[] items = {"Take photo", "Photo from Gallery"};  Alertdialog.builder Builder = new Alertdialog.builder (GetContext ()); Builder.setitems (items, new Dialoginterface.onclicklistener () {@Override public void OnClick (DialoginterfAce arg0, int arg1) {Addphoto ();  }  }); Builder.show ();} The most important thing is to call the layout method, according to the left and top fields in the layoutparams that we obtained in the measure phase, and to position each sub-view in good order. Then determine that the picture does not reach the maximum value of 9, the default is the last picture, and then set the Click event, Pop-up dialog box for the user to select the action. Draw does not need to be rewritten, using the ViewGroup default implementation. Attach the layout file <?xml version= "1.0" encoding= "Utf-8"? ><linearlayout xmlns:android= "http://schemas.android.com/apk/ Res/android "xmlns:app=" Http://schemas.android.com/apk/res-auto "android:layout_width=" Match_parent "Android: layout_height= "Match_parent" android:layout_margintop= "40DP" android:orientation= "vertical" >< Com.sw.demo.widget.NinePhotoView android:id= "@+id/photoview" android:layout_width= "Match_parent" Android:layout_h eight= "Wrap_content" app:ninephoto_hspace= "10DP" app:ninephoto_vspace= "10DP" app:rainbowbar_color= "@android: Color /holo_blue_bright "></com.sw.demo.widget.NinePhotoView></LinearLayout> finally add the program to run, Today custom ViewGroup Explain so much, I wish you every day have a new harvest, every day have a good mood ~~~niewphotoview.gifniewphotoview.gif

Android Custom ViewGroup (choose photos or take pictures)

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.