由於項目需要,需要做一個圓形的帶邊框並且里邊還有文字的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的功能了。 就不上圖了,該吃飯了。。。