由于项目需要,需要做一个圆形的带边框并且里边还有文字的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的功能了。 就不上图了,该吃饭了。。。