zoukankan      html  css  js  c++  java
  • Android自定义View-圆形印章

    前言:

    第一次写文章,可能有些地方文字表述得不清楚,见谅。

    做这个东西的灵感来源于之前公司发的一份清明节放假通知上的盖章,就有了做个类似这种圆形印章的View的想法。刚好今天也没什么工作,就试着实现出来。

    正文:

    先看效果:

    实现这个View,还是比较简单的,一是圆环,二是文字扇形排列,三是中间的圆形图片。

    下面上具体代码:

    public class StampView extends View {
    
        private static final int TEXT_SIZE = 32;  //文字大小
        private static final int OUTSIDE_RING_WIDTH = 10; //圆环宽度
        private static final float TEXT_ANGLE = 120f;  //文字扇形排列的角度
        private static final int RADIUS = 180;  //印章半径
        private static final int SPACING = 36;  //图片与文字间距
        private static final float STAMP_ROTATE = 15f;  //印章旋转角度
        
        private static final int TEXT_COLOR = 0xFF000000; //文字颜色
        private static final int CIRCLE_COLOR = 0xFFFF0000; //圆环颜色
        
        private String mText;
        private Bitmap source;
        
        private final Paint mTextPaint = new Paint();
        private final Paint mCirclePaint = new Paint();
        
        public StampView(Context context) {
            super(context);
            init();
        }
        
        public StampView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }
        
        public StampView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init();
        }
        
        private void init() {
            mTextPaint.setColor(TEXT_COLOR);
            mTextPaint.setTextAlign(Paint.Align.CENTER);
    
            mCirclePaint.setColor(CIRCLE_COLOR);
            mCirclePaint.setStyle(Paint.Style.STROKE);
            mCirclePaint.setAntiAlias(true);
            
            source = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
        }
        
        @Override
        protected void onDraw(Canvas canvas) {
            // 获取宽高
            int width = this.getWidth();
            int height = this.getHeight();
            
            mTextPaint.setTextSize(TEXT_SIZE);
            
            float textY = height / 2 - RADIUS + OUTSIDE_RING_WIDTH + TEXT_SIZE;
            mText = mText != null ? mText : "";
            // 把文字拆成字符数组
            char[] chs = mText.toCharArray();
            
            // 画圆环
            mCirclePaint.setStrokeWidth(OUTSIDE_RING_WIDTH);
            canvas.drawCircle(width / 2, height / 2, RADIUS - OUTSIDE_RING_WIDTH / 2, mCirclePaint);
            
            canvas.save();
            canvas.rotate(STAMP_ROTATE, width / 2, height / 2);
            
            // 中间圆形位图的半径
            int radius = RADIUS - OUTSIDE_RING_WIDTH - TEXT_SIZE - SPACING;
            Bitmap image = createCircleImage(source, radius * 2);
            canvas.drawBitmap(image, (width - image.getWidth()) / 2, (height - image.getHeight()) / 2,
                    mCirclePaint);
            image.recycle();
            
            canvas.rotate(-TEXT_ANGLE / 2, width / 2, height / 2);
            // 每个文字间的角度间隔
            float spaceAngle = TEXT_ANGLE / (chs.length - 1);
            for(int i = 0; i < chs.length; i++) {
                String s = String.valueOf(chs[i]);
                canvas.drawText(s, width / 2, textY, mTextPaint);
                canvas.rotate(spaceAngle, width / 2, height / 2);
            }    
            canvas.restore();
        }
        
        /**
         * 创建圆形位图
         * @param source 原图片位图
         * @param diameter 圆形位图的直径
         * @return
         */
        private Bitmap createCircleImage(Bitmap source, int diameter) {
            final Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setFilterBitmap(true);
                    
            int width = source.getWidth();
            int height = source.getHeight();
            Bitmap clipBitmap;
            if(width > height) {
                int x = (width - height) / 2;
                int y = 0;
                clipBitmap = Bitmap.createBitmap(source, x, y, height, height);
            } else if(width < height) {
                int x = 0;
                int y = (height - width) / 2;
                clipBitmap = Bitmap.createBitmap(source, x, y, width, width);
            } else {
                clipBitmap = source;
            }
            
            Bitmap scaledBitmap = Bitmap.createScaledBitmap(clipBitmap, diameter, diameter, true);
            Bitmap outputBitmap = Bitmap.createBitmap(diameter, diameter, Config.ARGB_8888);
            Canvas canvas = new Canvas(outputBitmap);
            canvas.drawCircle(diameter / 2, diameter / 2, diameter / 2, paint);
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
            canvas.drawBitmap(scaledBitmap, 0, 0, paint);
    //        source.recycle();
            clipBitmap.recycle();
            scaledBitmap.recycle();
            return outputBitmap;
        }
        
        public void setText(String text) {
            mText = text;
        }
    
        public String getText() {
            return mText;
        }
        
        public void setTextColor(int textColor) {
            mTextPaint.setColor(textColor);
        }
        
        public void setCircleColor(int circleColor) {
            mCirclePaint.setColor(circleColor);
        }
        
        public void setBitmap(int id) {
            source = BitmapFactory.decodeResource(getResources(), id);
        }
    }
  • 相关阅读:
    Systemd程序及相关命令
    深入理解SELinux
    Linux系统常见内核问题修复(转发)
    CentOS6.8单用户模式下修改密码
    CentOS6启动流程
    linux中的软、硬链接
    Linux中计划任务、周期性任务设置
    CentOS7.3将网卡命名方式设置为传统方式
    js判断字符串是否有下划线
    判断是否是微信打开
  • 原文地址:https://www.cnblogs.com/frames/p/4402689.html
Copyright © 2011-2022 走看看