zoukankan      html  css  js  c++  java
  • Android 自定义View (二) 进阶

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24300125

    继续自定义View之旅,前面已经介绍过一个自定义View的基础的例子,Android 自定义View (一),如果你还对自定义View不了解可以去看看。今天给大家带来一个稍微复杂点的例子。

    自定义View显示一张图片,下面包含图片的文本介绍,类似相片介绍什么的,不过不重要,主要是学习自定义View的用法么。

    还记得上一篇讲的4个步骤么:

    1、自定义View的属性
    2、在View的构造方法中获得我们自定义的属性
    [ 3、重写onMesure ]
    4、重写onDraw

    直接切入正题:

    1、在res/values/attr.xml

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <resources>  
    3.   
    4.     <attr name="titleText" format="string" />  
    5.     <attr name="titleTextSize" format="dimension" />  
    6.     <attr name="titleTextColor" format="color" />  
    7.     <attr name="image" format="reference" />  
    8.     <attr name="imageScaleType">  
    9.         <enum name="fillXY" value="0" />  
    10.         <enum name="center" value="1" />  
    11.     </attr>  
    12.   
    13.     <declare-styleable name="CustomImageView">  
    14.         <attr name="titleText" />  
    15.         <attr name="titleTextSize" />  
    16.         <attr name="titleTextColor" />  
    17.         <attr name="image" />  
    18.         <attr name="imageScaleType" />  
    19.     </declare-styleable>  
    20.   
    21. </resources>  


    2、在构造中获得我们的自定义属性:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /** 
    2.      * 初始化所特有自定义类型 
    3.      *  
    4.      * @param context 
    5.      * @param attrs 
    6.      * @param defStyle 
    7.      */  
    8.     public CustomImageView(Context context, AttributeSet attrs, int defStyle)  
    9.     {  
    10.         super(context, attrs, defStyle);  
    11.   
    12.         TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomImageView, defStyle, 0);  
    13.   
    14.         int n = a.getIndexCount();  
    15.   
    16.         for (int i = 0; i < n; i++)  
    17.         {  
    18.             int attr = a.getIndex(i);  
    19.   
    20.             switch (attr)  
    21.             {  
    22.             case R.styleable.CustomImageView_image:  
    23.                 mImage = BitmapFactory.decodeResource(getResources(), a.getResourceId(attr, 0));  
    24.                 break;  
    25.             case R.styleable.CustomImageView_imageScaleType:  
    26.                 mImageScale = a.getInt(attr, 0);  
    27.                 break;  
    28.             case R.styleable.CustomImageView_titleText:  
    29.                 mTitle = a.getString(attr);  
    30.                 break;  
    31.             case R.styleable.CustomImageView_titleTextColor:  
    32.                 mTextColor = a.getColor(attr, Color.BLACK);  
    33.                 break;  
    34.             case R.styleable.CustomImageView_titleTextSize:  
    35.                 mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,  
    36.                         16, getResources().getDisplayMetrics()));  
    37.                 break;  
    38.   
    39.             }  
    40.         }  
    41.         a.recycle();  
    42.         rect = new Rect();  
    43.         mPaint = new Paint();  
    44.         mTextBound = new Rect();  
    45.         mPaint.setTextSize(mTextSize);  
    46.         // 计算了描绘字体需要的范围  
    47.         mPaint.getTextBounds(mTitle, 0, mTitle.length(), mTextBound);  
    48.   
    49.     }  


    3、重写onMeasure

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. @Override  
    2. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  
    3. {  
    4.     // super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
    5.   
    6.     /** 
    7.      * 设置宽度 
    8.      */  
    9.     int specMode = MeasureSpec.getMode(widthMeasureSpec);  
    10.     int specSize = MeasureSpec.getSize(widthMeasureSpec);  
    11.   
    12.     if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate  
    13.     {  
    14.         Log.e("xxx", "EXACTLY");  
    15.         mWidth = specSize;  
    16.     } else  
    17.     {  
    18.         // 由图片决定的宽  
    19.         int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();  
    20.         // 由字体决定的宽  
    21.         int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();  
    22.   
    23.         if (specMode == MeasureSpec.AT_MOST)// wrap_content  
    24.         {  
    25.             int desire = Math.max(desireByImg, desireByTitle);  
    26.             mWidth = Math.min(desire, specSize);  
    27.             Log.e("xxx", "AT_MOST");  
    28.         }  
    29.     }  
    30.   
    31.     /*** 
    32.      * 设置高度 
    33.      */  
    34.   
    35.     specMode = MeasureSpec.getMode(heightMeasureSpec);  
    36.     specSize = MeasureSpec.getSize(heightMeasureSpec);  
    37.     if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate  
    38.     {  
    39.         mHeight = specSize;  
    40.     } else  
    41.     {  
    42.         int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height();  
    43.         if (specMode == MeasureSpec.AT_MOST)// wrap_content  
    44.         {  
    45.             mHeight = Math.min(desire, specSize);  
    46.         }  
    47.     }  
    48.     setMeasuredDimension(mWidth, mHeight);  
    49.   
    50. }  


    4、重写onDraw

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. @Override  
    2.     protected void onDraw(Canvas canvas)  
    3.     {  
    4.         // super.onDraw(canvas);  
    5.         /** 
    6.          * 边框 
    7.          */  
    8.         mPaint.setStrokeWidth(4);  
    9.         mPaint.setStyle(Paint.Style.STROKE);  
    10.         mPaint.setColor(Color.CYAN);  
    11.         canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);  
    12.   
    13.         rect.left = getPaddingLeft();  
    14.         rect.right = mWidth - getPaddingRight();  
    15.         rect.top = getPaddingTop();  
    16.         rect.bottom = mHeight - getPaddingBottom();  
    17.   
    18.         mPaint.setColor(mTextColor);  
    19.         mPaint.setStyle(Style.FILL);  
    20.         /** 
    21.          * 当前设置的宽度小于字体需要的宽度,将字体改为xxx... 
    22.          */  
    23.         if (mTextBound.width() > mWidth)  
    24.         {  
    25.             TextPaint paint = new TextPaint(mPaint);  
    26.             String msg = TextUtils.ellipsize(mTitle, paint, (float) mWidth - getPaddingLeft() - getPaddingRight(),  
    27.                     TextUtils.TruncateAt.END).toString();  
    28.             canvas.drawText(msg, getPaddingLeft(), mHeight - getPaddingBottom(), mPaint);  
    29.   
    30.         } else  
    31.         {  
    32.             //正常情况,将字体居中  
    33.             canvas.drawText(mTitle, mWidth / 2 - mTextBound.width() * 1.0f / 2, mHeight - getPaddingBottom(), mPaint);  
    34.         }  
    35.   
    36.         //取消使用掉的快  
    37.         rect.bottom -= mTextBound.height();  
    38.   
    39.         if (mImageScale == IMAGE_SCALE_FITXY)  
    40.         {  
    41.             canvas.drawBitmap(mImage, null, rect, mPaint);  
    42.         } else  
    43.         {  
    44.             //计算居中的矩形范围  
    45.             rect.left = mWidth / 2 - mImage.getWidth() / 2;  
    46.             rect.right = mWidth / 2 + mImage.getWidth() / 2;  
    47.             rect.top = (mHeight - mTextBound.height()) / 2 - mImage.getHeight() / 2;  
    48.             rect.bottom = (mHeight - mTextBound.height()) / 2 + mImage.getHeight() / 2;  
    49.   
    50.             canvas.drawBitmap(mImage, null, rect, mPaint);  
    51.         }  
    52.   
    53.     }  


    代码,结合注释和第一篇View的使用,应该可以看懂,不明白的留言。下面我们引入我们的自定义View:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     xmlns:tools="http://schemas.android.com/tools"  
    3.     xmlns:zhy="http://schemas.android.com/apk/res/com.zhy.customview02"  
    4.     android:layout_width="match_parent"  
    5.     android:layout_height="match_parent"  
    6.     android:orientation="vertical" >  
    7.   
    8.     <com.zhy.customview02.view.CustomImageView  
    9.         android:layout_width="wrap_content"  
    10.         android:layout_height="wrap_content"  
    11.         android:layout_margin="10dp"  
    12.         android:padding="10dp"  
    13.         zhy:image="@drawable/ic_launcher"  
    14.         zhy:imageScaleType="center"  
    15.         zhy:titleText="hello andorid ! "  
    16.         zhy:titleTextColor="#ff0000"  
    17.         zhy:titleTextSize="30sp" />  
    18.   
    19.     <com.zhy.customview02.view.CustomImageView  
    20.         android:layout_width="100dp"  
    21.         android:layout_height="wrap_content"  
    22.         android:layout_margin="10dp"  
    23.         android:padding="10dp"  
    24.         zhy:image="@drawable/ic_launcher"  
    25.         zhy:imageScaleType="center"  
    26.         zhy:titleText="helloworldwelcome"  
    27.         zhy:titleTextColor="#00ff00"  
    28.         zhy:titleTextSize="20sp" />  
    29.   
    30.     <com.zhy.customview02.view.CustomImageView  
    31.         android:layout_width="wrap_content"  
    32.         android:layout_height="wrap_content"  
    33.         android:layout_margin="10dp"  
    34.         android:padding="10dp"  
    35.         zhy:image="@drawable/lmj"  
    36.         zhy:imageScaleType="center"  
    37.         zhy:titleText="妹子~"  
    38.         zhy:titleTextColor="#ff0000"  
    39.         zhy:titleTextSize="12sp" />  
    40.   
    41. </LinearLayout>  


    我特意让显示出现3中情况:

    1、字体的宽度大于图片,且View宽度设置为wrap_content

    2、View宽度设置为精确值,字体的长度大于此宽度

    3、图片的宽度大于字体,且View宽度设置为wrap_content

    看看显示效果:

    怎么样,对于这三种情况所展示的效果都还不错吧。

    好了,就到这里,各位看官,没事留个言,顶一个呗~

    源码点击下载

  • 相关阅读:
    开发工具分享
    图形学杂记
    keyle的Shader-学习手札
    Keyle的3D数学-学习手札
    SuperStrange项目主页
    Unity3d基础知识(水文)
    和Keyle一起学ShaderForge – Custom Blinn-Phong
    和Keyle一起学ShaderForge – Create Base Shader
    和Keyle一起学ShaderForge
    和Keyle一起学StrangeIoc – 教程目录
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/5460940.html
Copyright © 2011-2022 走看看