• 自定义控件学习之canvas和paint相关知识点学习


    1,继承自view,实现ondraw方法:

        初始化画笔,TextPaint paint,并设置画笔属性:

          paint.setFlags(Paint.ANTI_ALIAS_FLAG):画笔抗锯齿。

          paint.setStyle(Paint.Style.STROKE):设置画笔样式,默认全部填充Full

            {  1.Paint.Style.STROKE:描边;

                2.Paint.Style.FILL_AND_STROKE:描边并填充

                3.Paint.Style.FILL:填充

            }

         paint.setStrokeCap(Paint.Cap.ROUND):画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式

           {   1,圆形样式    Cap.ROUND,

               2,方形样式  Cap.SQUARE 

           }

         paint.setColor(0xff00ff00):设置画笔颜色

         Canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint):利用TextPaint在canvas上绘制线条:坐标从(startX,startY)到(stopX,stopY),坐标点起点为左上角,起点为0,0

    2,在xml布局里面设置自定义布局控件

    package com.soyoungboy.customview.widget;
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.View;
    
    import com.example.customview.R;
    
    /**
     * 自定义view基础 练习
     * 
     * @author soyoungboy
     * 
     */
    public class CustomView extends View {
        public TextPaint paint;
        private float textHeight;
        private float fontSize = getResources().getDimensionPixelSize(
                R.dimen.default_font_size);
        private float density = getResources().getDisplayMetrics().density;
    
        public CustomView(Context context) {
            super(context);
            init(null, 0);
        }
    
        public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init(attrs, defStyleAttr);
        }
    
        public CustomView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs, 0);
        }
    
        /**
         * 初始化操作
         * 
         * @param attrs
         * @param defStyleAttr
         */
        private void init(AttributeSet attrs, int defStyleAttr) {
            // 初始化TextPaint
             paint = new TextPaint();
    
            // paint的默认字体大小
            Log.i("iSpring", "默认字体大小: " + paint.getTextSize() + "px");
    
            // paint的默认颜色
            Log.i("iSpring", "默认颜色: " + Integer.toString(paint.getColor(), 16));
    
            // paint的默认style是FILL,即填充模式
            Log.i("iSpring", "默认style: " + paint.getStyle().toString());
    
            // paint的默认cap是
            Log.i("iSpring", "默认cap: " + paint.getStrokeCap().toString());
    
            // paint默认的strokeWidth
            Log.i("iSpring", "默认strokeWidth: " + paint.getStrokeWidth() + "");
    
            paint.setFlags(Paint.ANTI_ALIAS_FLAG);// 设置为抗锯齿
            paint.setTextSize(fontSize);// 设置字体大小
    
            // 初始化textHeight
            textHeight = fontSize;
            // Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            // textHeight = Math.abs(fontMetrics.top) + fontMetrics.bottom;
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            drawAxis(canvas);
        }
    
        /**
         * 绘制坐标系
         * 
         * @param canvas
         */
        private void drawAxis(Canvas canvas) {
            int canvasWidth = canvas.getWidth();
            int canvasHeight = canvas.getHeight();
            //        置画笔样式,如果不设置,默认是全部填充(FILL)。可选项为:FILL,FILL_OR_STROKE,或STROKE 
            //        画笔样式分三种:
            //        1.Paint.Style.STROKE:描边
            //        2.Paint.Style.FILL_AND_STROKE:描边并填充
            //        3.Paint.Style.FILL:填充
    
            paint.setStyle(Paint.Style.STROKE);
            //        该方法用来设置我们画笔的 笔触风格 ,比如:ROUND,表示是圆角的笔触。
            //        那么什么叫笔触呢,其实很简单,就像我们现实世界中的笔,如果你用圆珠笔在纸上戳一点,
            //        那么这个点一定是个圆,即便很小,它代表了笔的笔触形状,如果我们把一支铅笔笔尖削成方形的,
            //        那么画出来的线条会是一条弯曲的“矩形”,这就是笔触的意思。
            //        除了ROUND,Paint.Cap还提供了另外两种类型:SQUARE和BUTT
            paint.setStrokeCap(Paint.Cap.ROUND);
            //当画笔样式(style)为STROKE或FILL_OR_STROKE时(空心样式时),设置笔刷的粗细度。
            paint.setStrokeWidth(6 * density);
            //用绿色画x轴,用蓝色画y轴
    
            //第一次绘制坐标轴
            //设置画笔颜色为绿色
            paint.setColor(0xff00ff00);//绿色
            //Canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
            //从开始点为0,0的地方绘制线条到canvasWidth,0坐标,也就是说,沿着x轴绘制线条
            canvas.drawLine(0, 0, canvasWidth, 0, paint);//绘制x轴
            //设置画笔颜色为蓝色
            paint.setColor(0xff0000ff);//蓝色,也就说沿着Y轴绘制线条
            //从开始点为0,0的地方绘制线条到0,canvasHeight坐标
            canvas.drawLine(0, 0, 0, canvasHeight, paint);//绘制y轴
        }
    }

     背景颜色绘制:

      canvas.drawARGB(a, r, g, b):其中a,r,g,b为0到255的int值,用来组成画布的背景颜色

      canvas.drawColor(Color.BLUE) :将会以颜色ARBG填充整个控件的Canvas背景

      canvas.drawColor(Color.BLUE, Mode.SCREEN) :绘制颜色,但是要制定一个mode

        mode参数:

        

        对应下图:

        

        对应如下规则:

           SRC :只绘制源图像

           DST :只绘制目标图像 

           DST_OVER :在源图像的顶部绘制目标图像 

           DST_IN :只在源图像和目标图像相交的地方绘制目标图像 

           DST_OUT :只在源图像和目标图像不相交的地方绘制目标图像 

           DST_ATOP :在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像 

           SRC_OVER :在目标图像的顶部绘制源图像 

           SRC_IN :只在源图像和目标图像相交的地方绘制源图像 

           SRC_OUT :只在源图像和目标图像不相交的地方绘制源图像 

           SRC_ATOP :在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像 

           XOR :在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容 

          LIGHTEN :获得每个位置上两幅图像中最亮的像素并显示 

           DARKEN :获得每个位置上两幅图像中最暗的像素并显示

          MULTIPLY :将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255 

           SCREEN :反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255) 

     如上代码ondraw里面代码:

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawARGB(168, 138, 179, 233);
        }

    效果:

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.RED);
        }

    效果:

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawColor(Color.BLUE, Mode.SCREEN);
        }


    绘制文字

     博客园里面有篇文字讲的很细,可以去看看:http://www.cnblogs.com/tianzhijiexian/p/4297664.html

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //设置抗锯齿
            paint.setAntiAlias(true);
            //控制文字大小
            paint.setTextSize(24);
            //控制文字颜色
            paint.setColor(Color.RED);
            //设置文字粗体
            paint.setFakeBoldText(true); 
            //设置是否显示下划线
            paint.setUnderlineText(true);
            //设置字体类型
            paint.setTypeface(Typeface.SANS_SERIF);
            //左上角倾斜
            paint.setTextSkewX(-0.25f);
            //文本删除线
            paint.setStrikeThruText(true);
            
            //第一个为显示的内容,第二个参数为文字显示的x轴坐标,第三个为Y坐标
            canvas.drawText("我是大帅哥", canvas.getWidth()/2, canvas.getHeight()/2, paint);
        }

    效果如下:


    绘制点:

    StrokeWidth  --  控制宽度
    color -- 控制颜色
    StrokeCap -- 控制形状
    通过drawpoint来进行绘制
    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            paint.setStrokeWidth(100);
            paint.setColor(Color.YELLOW);
    //        paint.setStrokeCap(Paint.Cap.SQUARE);
            paint.setStrokeCap(Paint.Cap.BUTT);
            canvas.drawPoint(canvas.getWidth()/3, canvas.getHeight()/3, paint);
        }

     效果:


    绘制方块 

     

    擦,还有这种:

    如上三种方法来进行绘制方块:

    canvas.drawcircle为绘制圆

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Rect r = new Rect(100, 100, 300, 300);
            //方块背后的颜色
            canvas.drawColor(Color.RED);
            //绘制方格的颜色
            paint.setColor(Color.WHITE);
            //绘制方格
            canvas.drawRect(r, paint);
            paint.setColor(Color.BLACK);
            //绘制黑色的圆
            canvas.drawCircle(200, 200, 100, paint);
        }

     绘制圆,style有三种:

    代码试试,看看效果:

    填充,填充轮廓和里面

    Fill或者Fill_AND_STROKE:

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Rect r = new Rect(100, 100, 300, 300);
            //方块背后的颜色
            canvas.drawColor(Color.RED);
            //绘制方格的颜色
            paint.setColor(Color.WHITE);
            //绘制方格
            canvas.drawRect(r, paint);
            paint.setColor(Color.BLACK);
            paint.setStyle(Style.FILL);
            //绘制黑色的圆
            canvas.drawCircle(200, 200, 100, paint);
        }

    效果如上图:

    设置为:

    Stoke,绘制轮廓

    paint.setStyle(Style.STROKE);

     


    绘制椭圆 

     虽然调用的是drawoval,其实还是主要通过RectF和上下左右的位置的计算来进行控制

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            int Width = canvas.getWidth();
            int height = canvas.getHeight()/2;
            float left = 10 * density;
            float right = Width-left;
            float top = height/4;
            float bottom = height/2+height/4;
            paint.setColor(Color.BLACK);
            paint.setStyle(Style.FILL);
            RectF f = new RectF(left, top, right, bottom);
            //绘制黄色的椭圆
            canvas.drawOval(f, paint);
        }

    paint.setStyle(Style.STROKE)为图2


    drawBitmap:绘制图片

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher);
            canvas.drawBitmap(mBmp , mBmp.getWidth(), mBmp.getHeight(), paint);  
            canvas.restore();
        }

    BitmpaUtils.drawableToBitmap方法代码,将drawable转换为bitmap:

    public static Bitmap drawableToBitmap(Context context, int resId) {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inPreferredConfig = Bitmap.Config.RGB_565;
            opt.inPurgeable = true;
            opt.inInputShareable = true;
            InputStream is = context.getResources().openRawResource(resId);
            return BitmapFactory.decodeStream(is, null, opt);
        }

    执行效果:

    缩放借助Matrix来实现:

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher);
            canvas.drawBitmap(mBmp , mBmp.getWidth(), mBmp.getHeight(), paint);  
            Matrix matrix=new Matrix();
            matrix.postScale(0.5f, 0.5f);
            Bitmap dstbmp=Bitmap.createBitmap(mBmp,0,0,mBmp.getWidth(),
                    mBmp.getHeight(),matrix,true);
            canvas.drawBitmap(dstbmp, 10, 10, null);
        }

    看下效果,宽高缩小一半:

    对图片进行旋转:

    matrix.postRotate(45);

    @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            Matrix matrix=new Matrix();
            matrix.postRotate(45);
            Bitmap mBmp = BitmapUtils.drawableToBitmap(context, R.drawable.ic_launcher);
            Bitmap dstbmp=Bitmap.createBitmap(mBmp,0,0,mBmp.getWidth(),
                    mBmp.getHeight(),matrix,true);
            canvas.drawBitmap(dstbmp, 10, 10, null);
        }

  • 相关阅读:
    Django tutorial part2
    Django tutorial part1
    webpy使用mysql数据库操作(web.database)
    Sicily 1031. Campus 解题报告
    Sicily 1321. Robot 解题报告
    Sicily 1940. Ordering Tasks 解题报告
    Sicily 1936. Knight Moves 解题报告
    Java多线程21:多线程下的其他组件之CyclicBarrier、Callable、Future和FutureTask
    Java多线程20:多线程下的其他组件之CountDownLatch、Semaphore、Exchanger
    Java多线程19:定时器Timer
  • 原文地址:https://www.cnblogs.com/androidsuperman/p/4999382.html
Copyright © 2020-2023  润新知