Android View measure (v) supports the margin attribute, starting with an exception

Source: Internet
Author: User



Look at the code first.


First, view Natsume

1. Custom Controls
public class Customviewgroup extends ViewGroup {... @Override protected void onmeasure (int widthmeasurespec,        int heightmeasurespec) {super.onmeasure (Widthmeasurespec, Heightmeasurespec);            Traverse all sub-views for Measure operation for (int i = 0; i < Getchildcount (); i++) {View child = Getchildat (i); if (child! = null && child.getvisibility ()! = View.gone) {measurechild (Child, Widthmeasuresp                EC, HEIGHTMEASURESPEC); Android:layout_margin properties that support child view settings marginlayoutparams Layoutparams = (marginlayoutparams) child.getlayoutpa                Rams ();            int marginleft = Layoutparams.leftmargin;    }} setmeasureddimension (Widthmeasurespec, Heightmeasurespec);  } @Override protected void OnLayout (Boolean changed, int left, int top, int. right, Int. bottom) {for (int i = 0; I < Getchildcount (); i++) {View Childview = Getchildat (i);//Only for the simplest code to reproduce the bug, allSub-views are randomly placed childview.layout (left, top, leave + childview.getmeasuredwidth (), Top + childview.getmeasuredheight ()); }    }}

Inherited from ViewGroup, mainly demonstrates how to support the margin property in a custom view, focusing on the Child.getlayoutparams () line, and then looking at how the layout file is used


2. Layout files
        <com.example.android.apis.customviewgroup            android:id= "@+id/custom_view_group"            android:layout_width= "Match_parent"            android:layout_height= "wrap_content" >            <textview                android:layout_width= "Wrap_ Content "                android:layout_height=" wrap_content "android:layout_margin=" 10dip "                android:text=" Love_world_ "/ >        </com.example.android.apis.CustomViewGroup>


Plays: android:layout_margin= "10dip" Margin property


3. Exceptions
Java.lang.classcastexception:android.view.viewgroup$layoutparams cannot is cast to android.view.viewgroup$ Marginlayoutparamsat com.example.android.apis.CustomViewGroup.onMeasure (customviewgroup.java:50) at Android.view.View.measure (view.java:16831) at Android.view.ViewGroup.measureChildWithMargins (viewgroup.java:5245 ) at Android.widget.LinearLayout.measureChildBeforeLayout (linearlayout.java:1410) at Android.widget.LinearLayout.measureHorizontal (linearlayout.java:1052) at Android.widget.LinearLayout.onMeasure ( linearlayout.java:590) at Android.view.View.measure (view.java:16831) at Android.view.ViewGroup.measureChildWithMargins (viewgroup.java:5245) at Android.widget.LinearLayout.measureChildBeforeLayout (linearlayout.java:1410) at Android.widget.LinearLayout.measureVertical (linearlayout.java:695) at Android.widget.LinearLayout.onMeasure ( linearlayout.java:588) at Android.view.View.measure (view.java:16831) at Android.view.ViewGroup.measureChildWithMargins (viewgroup.java:5245) at Android.widget.FrameLayoUt.onmeasure (framelayout.java:310) at Android.view.View.measure (view.java:16831) at Android.widget.LinearLayout.measureVertical (linearlayout.java:847) at Android.widget.LinearLayout.onMeasure ( linearlayout.java:588) at Android.view.View.measure (view.java:16831) at Android.view.ViewGroup.measureChildWithMargins (viewgroup.java:5245) at Android.widget.FrameLayout.onMeasure ( framelayout.java:310) at Com.android.internal.policy.impl.phonewindow$decorview.onmeasure (PhoneWindow.java:2586) At Android.view.View.measure (view.java:16831) at Android.view.ViewRootImpl.performMeasure (viewrootimpl.java:2189) At Android.view.ViewRootImpl.measureHierarchy (viewrootimpl.java:1352) at Android.view.ViewRootImpl.performTraversals (viewrootimpl.java:1535) at Android.view.ViewRootImpl.doTraversal ( viewrootimpl.java:1249) at Android.view.viewrootimpl$traversalrunnable.run (viewrootimpl.java:6364) at Android.view.choreographer$callbackrecord.run (choreographer.java:791) at Android.view.Choreographer.doCallbacks ( Choreographer.java:5In Android.view.Choreographer.doFrame (choreographer.java:561) at android.view.choreographer$ Framedisplayeventreceiver.run (choreographer.java:777) at Android.os.Handler.handleCallback (handler.java:730) at Android.os.Handler.dispatchMessage (handler.java:92) at Android.os.Looper.loop (looper.java:176) at Android.app.ActivityThread.main (activitythread.java:5419) at java.lang.reflect.Method.invokeNative (Native Method) At Java.lang.reflect.Method.invoke (method.java:525) at Com.android.internal.os.zygoteinit$methodandargscaller.run (zygoteinit.java:1209) at Com.android.internal.os.ZygoteInit.main (zygoteinit.java:1025) at Dalvik.system.NativeStart.main (Native Method)






The cause of the above exception, where did Layoutparams come from?
There are two ways to load a view: One is code AddView one is inflate.

1. Inflate method to load and add Layoutparams
Analysis of measure process, wrap_content and XML layout file parsing process in Android (Part I)




2. The following demo AddView way to add layoutparams


public class Mainactivity extends Activity {    @Overrideprotected void onCreate (Bundle savedinstancestate) { Super.oncreate (savedinstancestate); Setcontentview (R.layout.activity_main); Customviewgroup Customviewgroup = (customviewgroup) Findviewbyid (R.id.custom_view_group); CustomViewGroup.addView ( Createtextview ("Love_world_"));}    Private View Createtextview (String value) {        TextView TextView = new TextView (this);          Textview.settext ("A Child View");        Textview.settext (value);        Textview.setlayoutparams (New Viewgroup.marginlayoutparams (Layoutparams.wrap_content, LayoutParams.WRAP_CONTENT)) ;        return textView;}    }




2. Viewgroup.addview source, find out where to add layoutparams

Public abstract class ViewGroup extends view implements Viewparent, Viewmanager {public void AddView (View child) {    AddView (Child,-1); } public void AddView (view child, int index) {layoutparams params = Child.getlayoutparams ();//Sub-view Layoutparams            NULL is the processing mode if (params = = null) {params = Generatedefaultlayoutparams (); if (params = = null) {throw new IllegalArgumentException ("Generatedefaultlayoutparams () cannot return null"            );    }} addview (Child, index, params); } public void AddView (View child, int width, int height) {final Layoutparams params = Generatedefaultlayoutpara        MS ();        Params.width = width;        Params.height = height;    AddView (Child,-1, params);    } public void AddView (View child, Layoutparams params) {AddView (Child,-1, params); } public void AddView (View child, int index, layoutparams params) {if (DBG) {System.out.println(This + "AddView"); }//Addviewinner () would call Child.requestlayout () when setting the new Layoutparams//Therefore, we call Requestlayout () on ourselves before, so then the child's request//would be a blocked at our level Requestlayo        UT ();        Invalidate ();    Addviewinner (Child, index, params, false); }//Child View Default Layoutparams instance protected Layoutparams Generatedefaultlayoutparams () {return new Layoutparams (Layoutparams.    Wrap_content, layoutparams.wrap_content);  }//definition Layoutparams class public static class Layoutparams {public int width;public int height;public layoutparams (int width, int            Height) {this.width = width;        This.height = height; }}}


Here are the key

Public abstract class ViewGroup extends view implements Viewparent, Viewmanager {    private void Addviewinner (View child , int index, layoutparams params,            boolean preventrequestlayout) {        if (child.getparent () = null) {            throw new I Llegalstateexception ("The specified child already have a parent." +                    "You must call Removeview () on the child ' s parent First. ");        }        if (!checklayoutparams (params)) {            params = generatelayoutparams (params);        }        if (preventrequestlayout) {            child.mlayoutparams = params;        } else {            child.setlayoutparams (params);        }        ......    } Protected Boolean checklayoutparams (Viewgroup.layoutparams p) {        return  P! = null;    }}


By looking at the AddView add layoutparams code above, you can discover solutions that replicate these functions, creating layoutparams from the current custom view to inherit from Marginlayoutparams.


public class Customviewgroup extends ViewGroup {@Override protected void onmeasure (int widthmeasurespec, int heightmeas Urespec) {...}    @Override protected void OnLayout (Boolean changed, int left, int top, int. right, int bottom) {...}    @Override protected Layoutparams generatelayoutparams (Viewgroup.layoutparams p) {return new Layoutparams (p); } @Override protected Layoutparams generatedefaultlayoutparams () {return new Layoutparams (layoutparams .    Match_parent, layoutparams.wrap_content); } @Override Public Layoutparams generatelayoutparams (AttributeSet attrs) {return new Layoutparams (GE    Tcontext (), attrs);        }//Inherit from margin, support child View Android:layout_margin property public static class Layoutparams extends Marginlayoutparams {        Public Layoutparams (Context C, AttributeSet attrs) {super (C, attrs);        } public layoutparams (int width, int height) {Super (width, height); } publiC Layoutparams (Viewgroup.layoutparams source) {super (source);        } public Layoutparams (Viewgroup.marginlayoutparams source) {super (source); }    }}












Android View measure (v) supports the margin attribute, starting with an exception

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.