Android View system (9) custom View

Source: Internet
Author: User

Android View system (9) custom View
Preface

After learning the above articles, let's talk about the custom View. The custom View has always been regarded as a master skill, because there are too many situations, and the effect is changeable, but it must also follow certain rules. What we want to talk about is this rule. As for the ever-changing and cool effects, you will be able to play it slowly. However, it should be noted that there must be a degree in everything. After all, the custom View is not a standard control. If you do not design it, or consider performance, it will be counterproductive. In addition, adaptation may also cause problems, I suggest using system controls if you can use them.

1. Introduction to custom View

Custom Views are divided into two categories by the author. One is custom View and the other is custom ViewGroup; custom View can be divided into inherited View and inherited system control. This article first describes one of the two categories: Custom View.

2. inherit the custom View of the system control

This custom View is extended based on the system control. Generally, it adds new features or modifies the display effect. Generally, we process it in the onDraw () method. Here is a simple example:

public class InvalidTextView extends TextView {    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    public InvalidTextView(Context context) {        super(context);        initDraw();    }    public InvalidTextView(Context context, AttributeSet attrs) {        super(context, attrs);        initDraw();    }    public InvalidTextView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initDraw();    }    private void initDraw() {        mPaint.setColor(Color.RED);        mPaint.setStrokeWidth((float) 1.5);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int width = getWidth();        int height = getHeight();        canvas.drawLine(0, height / 2, width, height / 2, mPaint);    }}

This custom View inherits TextView and draws a red horizontal line in the onDraw () method. Next, reference this InvalidTextView in the layout:

   
  

Run the program to see the effect:

3. inherit the custom View of the View

Unlike the custom View inherited from the system control above, the implementation of the custom View inherited from the View is a little more complex, not just the onDraw () method, in addition, the wrap_content attribute and padding attribute settings must be taken into account during the implementation process. To facilitate the configuration of custom views, custom attributes are also provided to the outside. In addition, if you want to change the touch logic, you also need to override methods for touch events such as onTouchEvent.

Simple implementation of custom View inheriting View

Based on the above example, we will write another RectView class to inherit the View to draw a square:

public class RectView extends View {    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    private int mColor=Color.RED;    public RectView(Context context) {        super(context);        initDraw();    }    public RectView(Context context, AttributeSet attrs) {        super(context, attrs);        initDraw();    }    public RectView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        initDraw();    }    private void initDraw() {        mPaint.setColor(mColor);        mPaint.setStrokeWidth((float) 1.5);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int width = getWidth();        int height = getHeight();        canvas.drawRect(0, 0, width, height, mPaint);    }}

Reference RectView in layout:

  
  

Run the program to view the effect:

Processing the padding attribute

If I set the pading attribute in the layout file and find that it does not play any role, it seems that I have to process the padding attribute. I only need to modify it in the onDraw () method, consider the padding attribute when drawing a square:

 @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int paddingLeft=getPaddingLeft();        int paddingRight=getPaddingRight();        int paddingTop=getPaddingTop();        int paddingBottom=getPaddingBottom();        int width = getWidth()-paddingLeft-paddingRight;        int height = getHeight()-paddingTop-paddingBottom;        canvas.drawRect(0+paddingLeft, 0+paddingTop, width+paddingRight, height+paddingBottom, mPaint);    }

Modify the layout file to add the padding attribute:

    
  

Run the program to see the effect:

Process the wrap_content attribute

Modify the layout file so that the width of the RectView is the same for wrap_content and match_parent respectively:

For the cause of this situation, see Android View system (7) This article on the measure process of View parsing from source code. In this case, we need to specify a default width and height in the onMeasure () method. Set the default width and height when setting the wrap_content attribute:

  @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);        int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);        int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);        if(widthSpecMode==MeasureSpec.AT_MOST&&heightSpecMode==MeasureSpec.AT_MOST){            setMeasuredDimension(400,400);        }else if(widthSpecMode==MeasureSpec.AT_MOST){            setMeasuredDimension(400,heightSpecSize);        }else if(heightSpecMode==MeasureSpec.AT_MOST){            setMeasuredDimension(widthSpecSize,400);        }    }

Note that the unit of the parameter received by the setMeasuredDimension () method is px, to see the effect:

Custom Attributes

The controls in the android system start with android, such as android: layout_width. These are built-in attributes of the system. To facilitate the configuration of RectView attributes, we can also customize attributes, first, create attrs in the values directory. xml:

<code class="hljs xml"><!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--><resources>    <declare-styleable name="RectView">        <attr format="color" name="rect_color">    </attr></declare-styleable></resources></code>

This configuration file defines a custom attribute combination named RectView. We have defined the rect_color attribute in the format of color. Next, parse the value of the custom attribute in the RectView constructor:

Public RectView (Context context, AttributeSet attrs) {super (context, attrs); TypedArray mTypedArray = context. obtainStyledAttributes (attrs, R. styleable. rectView); // extract the rect_color attribute of the RectView attribute set. If the default value is not set. RED mColor = mTypedArray. getColor (R. styleable. rectView_rect_color, Color. RED); // collect mTypedArray in time after obtaining resources. recycle (); initDraw ();}

Finally, modify the layout file:

  
  

To use custom attributes, you must add schemas: xmlns: app = "your custom name. Finally, we configure the newly defined app: rect_color attribute android: color/holo_blue_light to see the effect:

Finally, the complete RectView code is pasted:

Package com. example. liuwangshu. mooncustomview; import android. content. context; import android. content. res. typedArray; import android. graphics. canvas; import android. graphics. color; import android. graphics. paint; import android. util. attributeSet; import android. view. view; public class RectView extends View {private Paint mPaint = new Paint (Paint. ANTI_ALIAS_FLAG); private int mColor = Color. RED; public RectView (Context context) {super (context); initDraw ();} public RectView (Context context, AttributeSet attrs) {super (context, attrs ); typedArray mTypedArray = context. obtainStyledAttributes (attrs, R. styleable. rectView); // extract the rect_color attribute of the RectView attribute set. If the default value is not set. RED mColor = mTypedArray. getColor (R. styleable. rectView_rect_color, Color. RED); // collect mTypedArray in time after obtaining resources. recycle (); initDraw ();} public RectView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); initDraw ();} private void initDraw () {mPaint. setColor (mColor); mPaint. setStrokeWidth (float) 1.5);} @ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec. getMode (widthMeasureSpec); int heightSpecMode = MeasureSpec. getMode (heightMeasureSpec); int widthSpecSize = MeasureSpec. getSize (widthMeasureSpec); int heightSpecSize = MeasureSpec. getSize (heightMeasureSpec); if (widthSpecMode = MeasureSpec. AT_MOST & heightSpecMode = MeasureSpec. AT_MOST) {setMeasuredDimension (400,400);} else if (widthSpecMode = MeasureSpec. AT_MOST) {setMeasuredDimension (400, heightSpecSize);} else if (heightSpecMode = MeasureSpec. AT_MOST) {setMeasuredDimension (widthSpecSize, 400) ;}@ Override protected void onDraw (Canvas canvas) {super. onDraw (canvas); int paddingLeft = getPaddingLeft (); int paddingRight = getPaddingRight (); int paddingTop = getPaddingTop (); int paddingBottom = trim (); int width = getWidth () -paddingLeft-paddingRight; int height = getHeight ()-paddingTop-paddingBottom; canvas. drawRect (0 + paddingLeft, 0 + paddingTop, width + paddingRight, height + paddingBottom, mPaint );}}

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.