• Android自定义View之CircleView


    Android自定义View之CircleView

    版权声明:本文为博主原创文章,未经博主允许不得转载。

    转载请表明出处:http://www.cnblogs.com/cavalier-/p/5999037.html

    前言

    大家好,我是Cavalier,这次和大家分享一下《Android自定义View之CircleView》,不废话,下面上效果图。

    Alt text

    分析

    需求

    1:随机换颜色的一个view  
    2:可以设置文字
    

    动手

    Setup1:继承自View,重写三个构造函数

    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可以直接指向第三个构造参数,所有初始化可以直接写在第三个构造参数中

    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函数

    @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获取了文字的绘制位置

    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()));
    }
    

    补充了这两个辅助函数后,代码已经完成了

    How to use?

    在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("哈哈");
    

    Souce Code

    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的用法。如文中有描述不巧当的地方请指出,谢谢。

    参考 : Android custom-components

  • 相关阅读:
    五:系统及数据库
    四:WEB源码扩展
    三:搭建安全拓展
    二:数据包扩展
    一:基础入门-概念名词
    LeetCode 11. Container With Most Water
    LeetCode 263. Ugly Number
    LeetCode 10. Regular Expression Matching
    LeetCode 58. Length of Last Word
    LeetCode 53. Maximum Subarray
  • 原文地址:https://www.cnblogs.com/cavalier-/p/5999037.html
Copyright © 2020-2023  润新知