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     @Override
106     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 source
124      *            color 这两个参数只能取一个
125      * @param min
126      * @return
127      */
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.xml 并定义以下内容

代码如下:

 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 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:sm="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.CustomImageView
10             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 >

 

其中:

xmlns:sm="http://schemas.android.com/apk/res/com.stock.manage.friend"

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

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

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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。