版权声明:本文为博主原创文章,未经博主容许不得转载。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的用法。如文中有描述不巧当的地方请指出,谢谢。