One, Android Custom view Properties
1. res/values/styles.xml
declare a custom attribute in the file:
<Resources> <!--Name is a declared "attribute collection" name, which can be arbitrarily taken, but preferably set to the same name as our view - <declare-styleablename= "Circleview"> <!--declare our property, name Default_size, value type is dimension type (DP,PX, etc.) - <attrname= "radius"format= "Dimension"></attr> <attrname= "Circle_color"format= "Color"></attr> </declare-styleable></Resources>
2. Get the property values for the corresponding settings in the custom view
PublicCircleview (Context context, @Nullable AttributeSet attrs) {Super(context, attrs); //that is, the label of the property collection, in the R file, the name is R.styleable+nameTypedArray TypedArray =context.obtainstyledattributes (Attrs, R.styleable.circleview); //The first parameter is the property within the property collection, R file name: R.styleable+ Property Collection name + Underscore + property name//The second parameter is, if this property is not set, the default value is setRadius = Typedarray.getdimensionpixeloffset (R.styleable.circleview_radius, 20); Color= Typedarray.getcolor (R.styleable.circleview_circle_color, 000000); //Finally, remember to recycle the Typedarray objecttypedarray.recycle (); }
3. Set the attribute value in the XML file (1) First you need to define the namespace xmlns:rc= "Http://schemas.android.com/apk/res-auto" (2) to set the property value Rc:radius Rc:circle_color
<LinearLayoutxmlns:android= "Http://schemas.android.com/apk/res/android"XMLNS:RC= "Http://schemas.android.com/apk/res-auto"Xmlns:tools= "Http://schemas.android.com/tools"Android:layout_width= "Match_parent"Android:layout_height= "Match_parent"android:orientation= "vertical"Tools:context= "Com.ruanchao.todaynews.UserViewActivity"> <Com.ruanchao.todaynews.view.CircleViewAndroid:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"Rc:radius= "50DP"Rc:circle_color= "#FF69B4"/> </LinearLayout>
Second, Android custom View1.onMeasure
protected void onmeasure (intint heightmeasurespec)
parameter in the
widthMeasureSpec
and
heightMeasureSpec包含了两层信息:测量模式和测量尺寸
the
(1)测量模式:
int widthmode = Measurespec.getmode (Widthmeasurespec);
Measurement Mode |
Express meaning |
UNSPECIFIED |
The parent container does not have any restrictions on the current view, and the current view can take any size (match_parent) |
Exactly |
The current size is the size that the current view should take (XML configuration fixed value ) |
At_most |
Current size is the maximum size available for the current view (wrap_content) |
(2)尺寸大小:
int widthsize = measurespec.getsize (Widthmeasurespec);
Example code:
Private intGetmysize (intDefaultSize,intMeasurespec) { intMysize =defaultsize; intmode =Measurespec.getmode (MEASURESPEC); intSize =measurespec.getsize (MEASURESPEC); Switch(mode) { CaseMeasurespec.unspecified: {//If no size is specified, it is set to the default sizeMysize =defaultsize; Break; } CaseMeasurespec.at_most: {//if the measurement mode is a maximum value of size//we will take the maximum size, you can also take other valuesMysize =size; Break; } Casemeasurespec.exactly: {//if it's a fixed size, don't change it .Mysize =size; Break; } } returnMysize;} @Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec) { Super. Onmeasure (Widthmeasurespec, Heightmeasurespec); intwidth = getmysize (100, Widthmeasurespec); intHeight = getmysize (100, Heightmeasurespec); if(Width <height) {Height=width; } Else{width=height; } setmeasureddimension (width, height);}
< Com.hc.studyview.MyView Android:layout_width = "Match_parent" android:layout_height= "100DP" android:background= "#ff0000" />
2.onDraw draws directly on the Artboard canvas object (1) The Invalidate method executes the OnDraw procedure, which can only be called in the UI thread (2) postinvalidate is called on a non-UI thread, eliminating the handler message call (3) Requestlayout will execute Onmeasure,onlayout, OnDrawThird, Android custom ViewGroupCustomizing the Viewgruup is going through the following steps: 1, depending on the size of each sub-view, determine the ViewGroup size (overriding the Onmeasure () method) 2, the view is placed in the ViewGroup (overriding the OnLayout () method) Sample code: Customizing ViewGroup Implementing LinearLayout LayoutsFirst step: Determine the ViewGroup size
@Overrideprotected voidOnmeasure (intWidthmeasurespec,intHeightmeasurespec) { intwith =measurespec.getsize (WIDTHMEASURESPEC); intHeight =measurespec.getsize (HEIGHTMEASURESPEC); intWithmode =Measurespec.getmode (WIDTHMEASURESPEC); intHeigthmode =Measurespec.getmode (HEIGHTMEASURESPEC); if(Getchildcount () = = 0) {//If there is no child view, the current viewgroup does not have the meaning to occupy spaceSetmeasureddimension (0, 0); return; } if(Withmode = = Measurespec.at_most && Heigthmode = =measurespec.at_most) { //high accumulation, maximum widthsetmeasureddimension (Getmaxchildwidth (), Gettotleheight ()); }Else if(Heigthmode = =measurespec.at_most) {setmeasureddimension (With,gettotleheight ()); }Else if(Withmode = =measurespec.at_most) {setmeasureddimension (Getmaxchildwidth (), height); } } /*** * Gets the maximum width of the child view*/ Private intgetmaxchildwidth () {intChildCount =Getchildcount (); intMaxWidth = 0; for(inti = 0; i < ChildCount; i++) {View Childview=Getchildat (i); if(Childview.getmeasuredwidth () >maxWidth) {MaxWidth=childview.getmeasuredwidth (); } } returnMaxWidth; } /*** * Add the height of all sub-view **/ Private intgettotleheight () {intChildCount =Getchildcount (); intHeight = 0; for(inti = 0; i < ChildCount; i++) {View Childview=Getchildat (i); Height+=childview.getmeasuredheight (); } returnheight; }
Step two: Placing the sub view in the ViewGroup
@Overrideprotected voidOnLayout (BooleanChangedintLeftintTopintRightintbottom) { intCount =Getchildcount (); intCurrentheigth = 0; //Place Sub-view individually for(inti = 0; I < count; i++) {View child=Getchildat (i); intChildheigth =child.getmeasuredheight (); Child.layout (left, currentheigth, right)+ Child.getmeasuredwidth (), Currentheigth +childheigth); Currentheigth+=childheigth; } }
Test XML
<Com.rc.studyview.MyViewGroupAndroid:layout_width= "Wrap_content"Android:layout_height= "Wrap_content"Android:background= "#ff9900"> <ButtonAndroid:layout_width= "100DP"Android:layout_height= "Wrap_content"Android:text= "BTN" /> <ButtonAndroid:layout_width= "200DP"Android:layout_height= "Wrap_content"Android:text= "BTN" /> <ButtonAndroid:layout_width= "50DP"Android:layout_height= "Wrap_content"Android:text= "BTN" /> </Com.rc.studyview.MyViewGroup>
Android Custom View, ViewGroup, and custom properties