版權聲明:本文爲博主原創文章,未經博主容許不得轉載。html
轉載請代表出處:http://www.cnblogs.com/cavalier-/p/5999037.htmljava
你們好,我是Cavalier,此次和你們分享一下《Android自定義View之CircleView》,不廢話,下面上效果圖。android
需求canvas
1:隨機換顏色的一個view 2:能夠設置文字
Setup1:繼承自View,重寫三個構造函數dom
public class CircleView extends View { public CircleView(Context context) { this(context,null); } public CircleView(Context context, AttributeSet attrs) { this(context, attrs,0); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } }
上面代碼中重寫了三個構造函數,其中第一個是用於直接new對象,第二個是從xml建立時沒有指定style時調用,第三個是指定了style時調用,經過this能夠直接指向第三個構造參數,全部初始化能夠直接寫在第三個構造參數中ide
Setup2:聲明所需的變量函數
private Paint mTextPain; //初始化畫筆 private String mText = ""; //初始化文字 private int radius; //當前View的半徑 ... public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); configPaint(); } private void configPaint() { mTextPain = new Paint(); mTextPain.setColor(Color.WHITE); //設置畫筆顏色爲白色 mTextPain.setAntiAlias(true); //開啓抗鋸齒,平滑文字和圓弧的邊緣 mTextPain.setTextAlign(Paint.Align.CENTER); //設置文本位於相對於原點的中間 }
上面代碼在第三個構造函數調用了configPaint函數字體
Setup3:從新onDraw函數ui
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth() / 2; //獲取寬度一半 int height = getHeight() / 2; //獲取高度一半 radius = Math.min(width, height); //設置半徑爲寬或者高的最小值 //paint bg mTextPain.setColor(Color.parseColor(getRandomColor())); //設置畫筆顏色爲隨機顏色 canvas.drawCircle(width, height, radius, mTextPain); //利用canvas畫一個圓 //paint font mTextPain.setColor(Color.WHITE); //設置畫筆白顏色 mTextPain.setTextSize(dp2px(16)); //設置字體大小爲16dp Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //獲取字體測量對象 canvas.drawText(mText, 0, mText.length(), radius //利用canvas畫上字 , radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain); }
上面代碼中先獲取到當前view的寬和高,取其中最小值做爲背景的半徑,設置了隨機顏色作背景,且利用FontMetrics獲取了文字的繪製位置this
Setup4:添加兩個輔助函數,dp2px和getRandomColor
/** * 給View設置文字 * @param str */ public void setText(String str) { if(!TextUtils.isEmpty(str)){ if(str.length()>1){ mText = str.substring(0,1); }else { mText = str; } }else { mText = ""; } invalidate(); }
固然,咱們須要將設置文字暴露給使用者,這裏利用了invalidate讓CircleView從新繪製一遍,目的是更改內中的文字
Setup5:添加兩個輔助函數,dp2px和getRandomColor
/** * dp轉px * * @param dp * @return */ private int dp2px(int dp) { // px = dp * (dpi / 160) DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); int dpi = metrics.densityDpi; return (int) (dp * (dpi / 160f) + 0.5f); } /** * 獲取隨機顏色 * * @return */ private String getRandomColor() { List<String> colorList = new ArrayList<String>(); colorList.add("#303F9F"); colorList.add("#FF4081"); colorList.add("#59dbe0"); colorList.add("#f57f68"); colorList.add("#f8b552"); colorList.add("#990099"); colorList.add("#90a4ae"); colorList.add("#7baaf7"); colorList.add("#4dd0e1"); colorList.add("#4db6ac"); colorList.add("#aed581"); colorList.add("#fdd835"); colorList.add("#f2a600"); colorList.add("#ff8a65"); colorList.add("#f48fb1"); colorList.add("#7986cb"); colorList.add("#DEB887"); colorList.add("#FF69B4"); return colorList.get((int) (Math.random() * colorList.size())); }
補充了這兩個輔助函數後,代碼已經完成了
在XML中使用
... <com.ram.testdemo.view.CircleView android:id="@+id/cv" android:layout_width="50dp" android:layout_height="50dp"/> ...
這裏注意調用時是使用你本身的Class文件全路徑。
在java中使用
CircleView mCircleView = (CircleView) findViewById(R.id.cv); mCircleView.setText("哈哈");
public class CircleView extends View { private Paint mTextPain; //初始化畫筆 private String mText = ""; //初始化文字 private int radius; //當前View的半徑 public CircleView(Context context) { this(context, null); } public CircleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); configPaint(); } private void configPaint() { mTextPain = new Paint(); mTextPain.setColor(Color.WHITE); //設置畫筆顏色爲白色 mTextPain.setAntiAlias(true); //開啓抗鋸齒,平滑文字和圓弧的邊緣 mTextPain.setTextAlign(Paint.Align.CENTER); //設置文本位於相對於原點的中間 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); int width = getWidth() / 2; //獲取寬度一半 int height = getHeight() / 2; //獲取高度一半 radius = Math.min(width, height); //設置半徑爲寬或者高的最小值 //paint bg mTextPain.setColor(Color.parseColor(getRandomColor())); //設置畫筆顏色爲隨機顏色 canvas.drawCircle(width, height, radius, mTextPain); //利用canvas畫一個圓 //paint font mTextPain.setColor(Color.WHITE); //設置畫筆白顏色 mTextPain.setTextSize(dp2px(16)); //設置字體大小爲16dp Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); //獲取字體測量對象 canvas.drawText(mText, 0, mText.length(), radius //利用canvas畫上字 , radius + Math.abs(fontMetrics.top + fontMetrics.bottom) / 2, mTextPain); } /** * 給View設置文字 * @param str */ public void setText(String str) { if(!TextUtils.isEmpty(str)){ if(str.length()>1){ mText = str.substring(0,1); }else { mText = str; } }else { mText = ""; } invalidate(); } /** * dp轉px * * @param dp * @return */ public int dp2px(int dp) { // px = dp * (dpi / 160) DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); int dpi = metrics.densityDpi; return (int) (dp * (dpi / 160f) + 0.5f); } /** * 獲取隨機顏色 * * @return */ private String getRandomColor() { List<String> colorList = new ArrayList<String>(); colorList.add("#303F9F"); colorList.add("#FF4081"); colorList.add("#59dbe0"); colorList.add("#f57f68"); colorList.add("#f8b552"); colorList.add("#990099"); colorList.add("#90a4ae"); colorList.add("#7baaf7"); colorList.add("#4dd0e1"); colorList.add("#4db6ac"); colorList.add("#aed581"); colorList.add("#fdd835"); colorList.add("#f2a600"); colorList.add("#ff8a65"); colorList.add("#f48fb1"); colorList.add("#7986cb"); colorList.add("#DEB887"); colorList.add("#FF69B4"); return colorList.get((int) (Math.random() * colorList.size())); } }
本篇中,咱們掌握了自定義View的invalidate重繪,和FontMetrics的文本位置測量,還了解onDraw中的canvas的用法。如文中有描述不巧當的地方請指出,謝謝。