Android custom View (2) Advanced

Source: Internet
Author: User

Reprinted please indicate the source: http://blog.csdn.net/lmj623565791/article/details/24300125

To continue the custom View journey, we have already introduced a basic example of a custom View, Android custom View (1 ), if you are not familiar with the custom View, you can check it out. Today, we will give you an example with a little complexity.

A custom View displays an image. The following content describes the text of the image, which is similar to the photo description. However, it is not important to learn how to use the custom View.

Do you still remember the four steps described in the previous article:

1. Custom View attributes
2. Obtain custom attributes in the View constructor.
[3. Rewrite onMesure]
4. Override onDraw

Start with the question:

1. In res/values/attr. xml

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="titleText" format="string" />    <attr name="titleTextSize" format="dimension" />    <attr name="titleTextColor" format="color" />    <attr name="image" format="reference" />    <attr name="imageScaleType">        <enum name="fillXY" value="0" />        <enum name="center" value="1" />    </attr>    <declare-styleable name="CustomImageView">        <attr name="titleText" />        <attr name="titleTextSize" />        <attr name="titleTextColor" />        <attr name="image" />        <attr name="imageScaleType" />    </declare-styleable></resources>

2. Get our custom attributes in the constructor:

/*** Initialize a specific custom type ** @ param context * @ param attrs * @ param defStyle */public CustomImageView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); TypedArray a = context. getTheme (). obtainStyledAttributes (attrs, R. styleable. customImageView, defStyle, 0); int n =. getIndexCount (); for (int I = 0; I <n; I ++) {int attr =. getIndex (I); switch (attr) {case R. styleable. customImageView_image: mImage = BitmapFactory. decodeResource (getResources (),. getResourceId (attr, 0); break; case R. styleable. customImageView_imageScaleType: mImageScale =. getInt (attr, 0); break; case R. styleable. customImageView_titleText: mTitle =. getString (attr); break; case R. styleable. customImageView_titleTextColor: mTextColor =. getColor (attr, Color. BLACK); break; case R. styleable. customImageView_titleTextSize: mTextSize =. getDimensionPixelSize (attr, (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_SP, 16, getResources (). getDisplayMetrics (); break;}. recycle (); rect = new Rect (); mPaint = new Paint (); mTextBound = new Rect (); mPaint. setTextSize (mTextSize); // calculates the mPaint range required to describe the font. getTextBounds (mTitle, 0, mTitle. length (), mTextBound );}

3. Override onMeasure

@ Overrideprotected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {// super. onMeasure (widthMeasureSpec, heightMeasureSpec);/*** set the width */int specMode = MeasureSpec. getMode (widthMeasureSpec); int specSize = MeasureSpec. getSize (widthMeasureSpec); if (specMode = MeasureSpec. EXACTLY) // match_parent, accurate {Log. e ("xxx", "EXACTLY"); mWidth = specSize;} else {// width int desireByImg = getPaddingLeft () + getPaddingRight () + mImage. getWidth (); // The width int desireByTitle = getPaddingLeft () + getPaddingRight () + mTextBound determined by the font. width (); if (specMode = MeasureSpec. AT_MOST) // wrap_content {int desire = Math. max (desireByImg, desireByTitle); mWidth = Math. min (desire, specSize); Log. e ("xxx", "AT_MOST") ;}/ ***** set height */specMode = MeasureSpec. getMode (heightMeasureSpec); specSize = MeasureSpec. getSize (heightMeasureSpec); if (specMode = MeasureSpec. EXACTLY) // match_parent, accurate {mHeight = specSize;} else {int desire = getPaddingTop () + getPaddingBottom () + mImage. getHeight () + mTextBound. height (); if (specMode = MeasureSpec. AT_MOST) // wrap_content {mHeight = Math. min (desire, specSize) ;}} setMeasuredDimension (mWidth, mHeight );}

4. Override onDraw

@ Overrideprotected void onDraw (Canvas canvas) {// super. onDraw (canvas);/*** border */mPaint. setStrokeWidth (4); mPaint. setStyle (Paint. style. STROKE); mPaint. setColor (Color. CYAN); canvas. drawRect (0, 0, getMeasuredWidth (), getMeasuredHeight (), mPaint); rect. left = getPaddingLeft (); rect. right = mWidth-getPaddingRight (); rect. top = getPaddingTop (); rect. bottom = mHeight-getPaddingBottom (); mPaint. setColor (mTextColor); mPaint. setStyle (Style. FILL);/*** the current width is smaller than the font width, and the font is changed to xxx... */if (mTextBound. width ()> mWidth) {TextPaint paint = new TextPaint (mPaint); String msg = TextUtils. ellipsize (mTitle, paint, (float) mWidth-getPaddingLeft ()-getPaddingRight (), TextUtils. truncateAt. END ). toString (); canvas. drawText (msg, getPaddingLeft (), mHeight-getPaddingBottom (), mPaint);} else {// normal, center the font in the canvas. drawText (mTitle, mWidth/2-mTextBound. width () * 1.0f/2, mHeight-getPaddingBottom (), mPaint);} // cancel the use of quick rect. bottom-= mTextBound. height (); if (mImageScale = IMAGE_SCALE_FITXY) {canvas. drawBitmap (mImage, null, rect, mPaint);} else {// calculates the rect of the rectangular range centered. left = mWidth/2-mImage. getWidth ()/2; rect. right = mWidth/2 + mImage. getWidth ()/2; rect. top = (mHeight-mTextBound. height ()/2-mImage. getHeight ()/2; rect. bottom = (mHeight-mTextBound. height ()/2 + mImage. getHeight ()/2; canvas. drawBitmap (mImage, null, rect, mPaint );}}

Code, combined with comments and the use of the first View, should be understandable, do not understand the message. Next we will introduce our custom View:

<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" xmlns: zhy = "http://schemas.android.com/apk/res/com.zhy.customview02" android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "vertical"> <com. zhy. customview02.view. customImageView android: layout_width = "wrap_content" android: layout_height = "wrap _ Content "android: layout_margin =" 10dp "android: padding =" 10dp "zhy: image =" @ drawable/ic_launcher "zhy: imageScaleType =" center "zhy: titleText = "hello andorid! "Zhy: titleTextColor =" # ff0000 "zhy: titleTextSize =" 30sp "/> <com. zhy. customview02.view. customImageView android: layout_width = "100dp" android: layout_height = "wrap_content" android: layout_margin = "10dp" android: padding = "10dp" zhy: image = "@ drawable/ic_launcher" zhy: imageScaleType = "center" zhy: titleText = "helloworldwelcome" zhy: titleTextColor = "#00ff00" zhy: titleTextSize = "20sp"/> <com. zhy. customview02.view. CustomImageView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_margin = "10dp" android: padding = "10dp" zhy: image = "@ drawable/lmj" zhy: imageScaleType = "center" zhy: titleText = "~ "Zhy: titleTextColor =" # ff0000 "zhy: titleTextSize =" 12sp "/> </LinearLayout>

I specifically asked the display to show 3 errors:

1. The font width is greater than the image width, and the View width is set to wrap_content.

2. Set the View width to an exact value. The font length is greater than this width.

3. The image width is greater than the font and the View width is set to wrap_content.

Check the display effect:


How about it? The effect shown in the three cases is good.


Okay, so here you are. You can leave a comment ~


Download source code




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.