你的位置:首页 > 操作系统

[操作系统]Android自定义带边框的圆形view


由于项目需要,需要做一个圆形的带边框并且里边还有文字的view →_→

↓↓↓↓这样↓↓↓↓

如果在布局文件中做的话是非常麻烦的,而且复用性也不高。所以想到用自定义一个view的来实现该功能,这样封装性和复用性就会相对提高,可方便在以后类似的项目中使用。可能也有同学有过这样的需求,所以在这分享出来供大家参考,不足之处还请多多指点。

看代码:

 1package com.stock.manage.friend.view;import android.content.Context;

2 import android.content.res.TypedArray;
 3 import android.graphics.Bitmap; 4 import android.graphics.Bitmap.Config; 5 import android.graphics.BitmapFactory; 6 import android.graphics.Canvas; 7 import android.graphics.Color; 8 import android.graphics.Paint; 9 import android.graphics.Paint.FontMetrics; 10 import android.graphics.PorterDuff; 11 import android.graphics.PorterDuffXfermode; 12 import android.util.AttributeSet; 13 import android.view.View; 14  15 /** 16  * 自定义View 实现圆 圆形等效果 17  * @author chengzijian 18  *  19 */ 20 public class CustomImageView extends View { 21  22   /** 23    * 图片 24   */ 25   private Bitmap mSrc; 26  27   /** 28    * 控件的宽度 29   */ 30   private int mWidth; 31   /** 32    * 控件的高度 33   */ 34   private int mHeight; 35   /** 36    *内颜色 37   */ 38   private int inColor; 39   /** 40    * 边框颜色 41   */ 42   private int outColor; 43   /** 44    *边框粗细 45   */ 46   private int outStrokeWidth; 47   /** 48    * 文字 49   */ 50   private String mText; 51   /** 52    * 文字颜色 53   */ 54   private int mTextColor; 55   /** 56    * 文字大小 57   */ 58   private float mTextSize; 59  60   public CustomImageView(Context context, AttributeSet attrs) { 61     this(context, attrs, 0); 62   } 63  64   public CustomImageView(Context context) { 65     this(context, null); 66   } 67  68   /** 69    * 初始化一些自定义的参数 70    *  71    * @param context 72    * @param attrs 73    * @param defStyle 74   */ 75   public CustomImageView(Context context, AttributeSet attrs, int defStyle) { 76     super(context, attrs, defStyle); 77  78     TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.StockManage); 79     mSrc = BitmapFactory.decodeResource(getResources(), array.getResourceId(R.styleable.StockManage_icon, -1)); 80     if (mSrc == null) { 81       inColor = array.getColor(R.styleable.StockManage_inColor, Color.WHITE); 82     } 83     mTextColor = array.getColor(R.styleable.StockManage_textColor, Color.BLACK); 84     outColor = array.getColor(R.styleable.StockManage_outColor, -1); 85     outStrokeWidth = array.getDimensionPixelSize(R.styleable.StockManage_stroke, 0); 86     mWidth = array.getDimensionPixelSize(R.styleable.StockManage_width, 0); 87     mHeight = array.getDimensionPixelSize(R.styleable.StockManage_height, 0); 88     mText = array.getString(R.styleable.StockManage_text); 89     mTextSize = array.getDimension(R.styleable.StockManage_textSize,R.dimen.text_size_sub);// 如果设置为DP等单位,会做像素转换  90     //释放资源 91     array.recycle(); 92   } 93  94   /** 95    * 计算控件的高度和宽度 96   */ 97   @Override 98   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 99     setMeasuredDimension(mWidth, mHeight);100   }101 102   /**103    * 绘制104   */105   @Override106   protected void onDraw(Canvas canvas) {107 108     int min = Math.min(mWidth, mHeight);109     /**110      * 长度如果不一致,按小的值进行压缩111     */112     if (mSrc != null) {113       mSrc = Bitmap.createScaledBitmap(mSrc, min, min, false);114       canvas.drawBitmap(createCircleImage(mSrc, min), 0, 0, null);115     } else {116       canvas.drawBitmap(createCircleImage(null, min), 0, 0, null);117     }118   }119 120   /**121    * 根据原图和边长绘制圆形图片122    * 123    * @param source124    *      color 这两个参数只能取一个125    * @param min126    * @return127   */128   private Bitmap createCircleImage(Bitmap source, int min) {129 130     final Paint paint = new Paint();131     paint.setAntiAlias(true);132     Bitmap target = Bitmap.createBitmap(min, min, Config.ARGB_8888);133     /**134      * 产生一个同样大小的画布135     */136     Canvas canvas = new Canvas(target);137     /**138      * 首先绘制圆形139     */140     canvas.drawCircle(min / 2, min / 2, min / 2, paint);141 142     /**143      * 使用SRC_IN,参考上面的说明144     */145     paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));146     /**147      * 绘制图片148     */149     if (source != null)// 画图片150       canvas.drawBitmap(source, 0, 0, paint);151     else { // 画圆152       paint.setColor(inColor);153       canvas.drawCircle(min / 2, min / 2, min / 2, paint);154     }155 156     if (outColor != 0) {157       // 让画出的图形是空心的158       paint.setStyle(Paint.Style.STROKE);159       // 设置画出的线的 粗细程度160       paint.setStrokeWidth(outStrokeWidth);161       paint.setColor(outColor);162       canvas.drawCircle(min / 2, min / 2, min / 2, paint);163     }164     if(mText != null){165       // 让画出的图形是实心的166       paint.setStyle(Paint.Style.FILL);167       paint.setStrokeWidth(1);168       if(mTextColor != 0 ){169         paint.setColor(mTextColor);170       }171       if(mTextSize != 0 ){172         paint.setTextSize(mTextSize);173       }174       paint.setTextAlign(Paint.Align.CENTER);175       FontMetrics fm = paint.getFontMetrics(); 176       //得到文字的高度177       float fFontHeight = (float)Math.ceil(fm.descent - fm.ascent); 178       179       canvas.drawText(mText, mWidth/2, mHeight/2+fFontHeight/4, paint);180     }181     return target;182   }183 184   //设置文字185   public void setText(String string) {186     mText = string;187     //重绘188     invalidate();189     requestLayout();190   }192 }

这段代码其实也很简单,主要就是初始化参数信息并画圆和文字的, 代码中大部分的注释都写了,这里就不在描述。

做的的自定义view,难免少不了自定属性。上边代码中78行使用到的 R.styleable.StockManage 就是我们要定义的属性。

需要在values文件夹中新建arrays.

代码如下:

 1   <declare-styleable name="StockManage"> 2     <attr name="width" format="dimension" /><!-- 宽度 --> 3     <attr name="height" format="dimension" /><!-- 高度 --> 4     <attr name="inColor" format="color" /><!-- 圈内颜色 --> 5     <attr name="outColor" format="color" /><!-- 圈外颜色 --> 6     <attr name="textColor" format="color" /><!-- 颜色--> 7     <attr name="stroke" format="dimension" /><!-- 圆圈的宽度 --> 8     <attr name="textSize" format="dimension" /><!-- 字体大小 --> 9     <attr name="text" format="string" /><!-- 字 -->10     <attr name="icon" format="reference" /><!-- 图片 -->11   </declare-styleable>

这段代码中的 name="StockManage" 就是我们要调用的的名称。里面的字段调动办法为 name_name, 前面的name是StockManage后面的是属性的name。

比如:

mTextColor = array.getColor(R.styleable.StockManage_textColor, Color.BLACK);

对自定义属性不太了解的同学,可去查看下相关的资料。。。

 

现在我们自定义的view已经写完了。接着 看使用方法。

我们在布局文件中使用:

 1 <??> 2 <LinearLayout ="http://schemas.android.com/apk/res/android" 3   ="http://schemas.android.com/apk/res/com.stock.manage.friend" 5   android:layout_width="match_parent" 6   android:layout_height="match_parent" 7   android:orientation="vertical" > 8  9     <com.stock.manage.friend.view.CustomImageView10       android:id="@+id/my_view"11       android:layout_width="wrap_content"12       android:layout_height="wrap_content"13       sm:height="100dip"14       sm:inColor="@color/white"15       sm:outColor="@color/black"16       sm:stroke="2dip"17       sm:text="文字"18       sm:textColor="@color/black"19       sm:textSize="12sp"20       sm:width="100dip" />21 22 </LinearLayout >

 

其中:

com.stock.manage.friend"

定义的是命名空间。黑色字体是我的包名。sm是名称。这样就可以使用arrays下面的属性了。

调用方法就是 sm:width="100dip"。类似这样。

这样就实现了自定义圆形view的功能了。 就不上图了,该吃饭了。。。