一、如何创建自定义的View类

①、创建一个继承android.view.View类的Java类,并且重写构造方法(至少需要重写一个构造方法)

②、根据需要重写其他方法

③、在项目的活动中,创建并实例化自定义的View类,然后将其添加到布局管理器中(添加到布局管理器的方法:布局管理器.addView())

二、View类常用的函数

①、onDraw() 当组件将要绘制它的内容时

②、onFinishInflate() 回调方法,当应用从XML加载该组件并用它构建界面之后调用的方法

③、onMeasure() 检测View组件及其子组件的大小

④、onLayout() 当该组件需要分配其子组件的位置、大小时

⑤、onSizeChange() 当该组件的大小被改变时

⑥、onKeyDown 当按下某个键盘时

⑦、onKeyUp 当松开某个键盘时

⑧、onTrackballEvent 当发生轨迹球事件时

⑨、onTouchEvent 当发生触屏事件时

⑩、onWindowFocusChanged(boolean) 当该组件得到、失去焦点时

11)、onAtrrachedToWindow() 当把该组件放入到某个窗口时

12)、onDetachedFromWindow() 当把该组件从某个窗口上分离时触发的方法

13)、onWindowVisibilityChanged(int): 当包含该组件的窗口的可见性发生改变时触发的方法

三、将自定义的Viewl类添加到相对应的窗口

方式一:

布局管理器  变量名 = (布局管理器)findViewById(R.id.ID)

类  变量名A = new 类(this)

布局管理器.addView(变量名A)

方式二:

在xml布局中添加

四、Android自定义View的构造函数

有两种方式自定义构造函数

方式一:

每个构造函数分别调用基类的构造函数,再调用一个公共的初始化方法做额外的初始化工作

 public class MyView extends ListView {
     public MyView(Context context) {
         super(context);
         sharedConstructor();
     }

     public MyView(Context context, AttributeSet attrs) {
         super(context, attrs);
         sharedConstructor();
     }

     public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         sharedConstructor();
     }

     private void sharedConstructor() {
         // Do some initialize work.
     }
 }

方式二:

级联式调用,每一个构造函数调用比它多一个参数的构造函数,最后一个构造函数调用基类的构造函数,最后在做一些额外的初始化工作

 public class MyView extends ListView {
     public MyView(Context context) {
         this(context, null);
     }

     public MyView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }

     public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);

         // Other initialize work.
     }
 }

注:

建议采用第一种方式。因为第二种方法在某些情况下会出现问题,比如你自定义的View继承自ListView或TextView时,ListView或TextView内部的构造函数有一个默认的defStyle, 第二种方法调用时defStyle会传入0,这将覆盖基类中默认的defStyle,进而导致一系列问题。

五、Canvas 和 Paint

Canvas表示画布,Paint代表画笔

1)、Paint的属性

       // 设置字体颜色
        paint.setColor(Color.RED);
        // 防锯齿
        paint.setAntiAlias(true);  

        //设置颜色过滤器,可以在绘制颜色时实现不用颜色的变换效果
        paint.setColorFilter(ColorFilter);   

        //如果该项设置为true,则图像在动画进行中会滤掉对Bitmap图像的优化操作,加      //快显示
        //速度,本设置项依赖于dither和xfermode的设置
        paint.setFilterBitmap(true);   

        //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的粗细度
        paint.setStrokeWidth(10f);
        //设置绘制路径的效果,如点画线等
        paint.setPathEffect(PathEffect);   

        //设置图像效果,使用Shader可以绘制出各种渐变效果
        paint.setShader(Shader);   

        //设置MaskFilter,可以用不同的MaskFilter实现滤镜的效果,如滤化,立体等
        paint.setMaskFilter(MaskFilter);   

        //在图形下面设置阴影层,产生阴影效果,radius为阴影的角度,dx和dy为阴影在x轴和y轴上的距离,color为阴影的颜色
        paint.setShadowLayer(float radius ,float dx,float dy,int color);   

        //设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE
        paint.setStyle(Paint.Style);   

        //当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,圆形样式ROUND,或方形样式SQUARE  BUTT
        paint.setStrokeCap(Paint.Cap);   

        //设置绘制时画笔与图形的结合方式,METER\ROUND\BEVEL  平滑效果
        paint.setSrokeJoin(Paint.Join);   

        // 字体下划线
        paint.setUnderlineText(true);
        // 暂时不知,有清楚的可以告诉我,谢谢
        paint.setLinearText(true);
        // 字体加粗
        paint.setFakeBoldText(true);
        // 防抖动
        paint.setDither(true);
        // 透明度
        paint.setAlpha(a);  

2)、如何获取一个Canvas对象

方式一:通过重写View.onDraw方法,View中的Canvas对象会被当做参数传递过来,我们操作这个Canvas,效果会直接反应在View中

方式二:自己创建一个Canvas对象。从上面的基本要素可以明白,一个Canvas对象一定是结合了一个Bitmap对象的。所以一定要为一个Canvas对象设置一个Bitmap对象

 //得到一个Bitmap对象,当然也可以使用别的方式得到。但是要注意,改bitmap一定要是mutable(异变的)
         Bitmap b = Bitmap.createBitmap(100,100, Bitmap.Config.ARGB_8888);
         Canvas c = new Canvas(b);
         /*先new一个Canvas对象,在调用setBitmap方法,一样的效果
          * Canvas c = new Canvas();
          * c.setBitmap(b);
          */

方式三:调用SurfaceHolder.lockCanvas(),返回一个Canvas对象;可以在 surfaceView 或 TextureView中使用

2.1)、Canvas可以绘制的内容

       //填充
      drawARGB(int a, int r, int g, int b)
      drawColor(int color)
      drawRGB(int r, int g, int b)
      drawColor(int color, PorterDuff.Mode mode)

     //几何图形
     canvas.drawArc  //(扇形)

     canvas.drawCircle  //(圆)

     canvas.drawOval  //(椭圆)

     canvas.drawLine  //(线)

     canvas.drawPoint  //(点)

     canvas.drawRect  //(矩形)

     canvas.drawRoundRect  //(圆角矩形)

     canvas.drawVertices  //(顶点)

     cnavas.drawPath  //(路径)

       //图片
       canvas.drawBitmap  //(位图)

       canvas.drawPicture   //(图片)

       //文本
       canvas.drawText     //Canvas绘制常用图形的方法如下:

    绘制直线:canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint);

    绘制矩形:canvas.drawRect(float left, float top, float right, float bottom, Paint paint);

    绘制圆形:canvas.drawCircle(float cx, float cy, float radius, Paint paint);

    绘制字符:canvas.drawText(String text, float x, float y, Paint paint);

    绘制图形:canvas.drawBirmap(Bitmap bitmap, float left, float top, Paint paint);

2.1)、Canvas的保存和回滚

Canvas还提供了保存和回滚属性的方法(save和restore),比如你可以先保存目前画纸的位置(save),然后旋转90度,向下移动100像素后画一些图形,画完后调用restore方法返回到刚才保存的位置

 /**
      * 保存当前的matrix和clip到私有的栈中(Skia内部实现)。任何matrix变换和clip操作都会在调用restore的时候还原。
      * @return 返回值可以传入到restoreToCount()方法,以返回到某个save状态之前。
      */
     public native int save();

     /**
      * 传入一个标志,来表示当restore 的时候,哪些参数需要还原。该参数定义在Canvas中,参照下面。
      * save()方法默认的是还原matrix和clip,但是可以使用这个方法指定哪些需要还原。并且只有指定matrix和clip才有效,其余的几个参数是
      * 用于saveLayer()和saveLayerAlpha()方法 的。
      */
     public native int save(int saveFlags);

     /**
      * 回到上一个save调用之前的状态,如果restore调用的次数大于save方法,会出错。
      */
     public native void restore();

      /**
      * 返回栈中保存的状态,值等译 save()调用次数-restore()调用次数
      */
     public native int getSaveCount();

     /**
      * 回到任何一个save()方法调用之前的状态
      */
     public native void restoreToCount(int saveCount);

 /**saveFlags的参数*/
  public static final int MATRIX_SAVE_FLAG = 0x01;//需要还原Matrix
     public static final int CLIP_SAVE_FLAG = 0x02;//需要还原Clip
 /**下面三个参数在saveLayer的时候使用,具体作用,没有搞明白*/
    public static final int HAS_ALPHA_LAYER_SAVE_FLAG = 0x04;
   public static final int FULL_COLOR_LAYER_SAVE_FLAG = 0x08;
   public static final int CLIP_TO_LAYER_SAVE_FLAG = 0x10;
     public static final int ALL_SAVE_FLAG = 0x1F; //还原所有

 /*关于saveLayer的具体flags还不大明白它的含义,具体怎么使用在下面例子中*/
  public int saveLayer(RectF bounds, Paint paint, int saveFlags)
 public int saveLayer(float left, float top, float right, float bottom,
                          Paint paint, int saveFlags)
  public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags)
 public int saveLayerAlpha(float left, float top, float right, float bottom,
                               int alpha, int saveFlags)

2.3)、Canvas的转换

Canvas还提供了一系列位置转换的方法:rorate、scale、translate、skew(扭曲)等

 @Override
         protected void onDraw(Canvas canvas) {
             canvas.translate(100, 100);
             canvas.drawColor(Color.RED);//可以看到,整个屏幕依然填充为红色

             canvas.drawRect(new Rect(-100, -100, 0, 0), new Paint());//缩放了
             canvas.scale(0.5f, 0.5f);
             canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());

             canvas.translate(200, 0);
             canvas.rotate(30);
             canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());//旋转了

             canvas.translate(200, 0);
             canvas.skew(.5f, .5f);//扭曲了
             canvas.drawRect(new Rect(0, 0, 100, 100), new Paint());
             // canvas.setMatrix(matrix);//Matrix的使用在后面在是。
         }

3)、Color类

  ①、Android系统中颜色的常用表示方法有以下3种:

  (1)int color = Color.BLUE;

  (2)int color = Color.argb(150,200,0,100);

  (3)在xml文件中定义颜色;

  ②、在实际应用当中,我们常用的颜色有以下一些,其颜色常量及其表示的颜色如下所示:

  Color.BLACK      黑色                                       Color.GREEN                  绿色

  Color.BLUE        蓝色                                       Color.LTGRAY                浅灰色

  Color.CYAN       青绿色                                     Color.MAGENTA              红紫色

  Color.DKGRAY    灰黑色                                    Color.RED                      红色

  Color.YELLOW    黄色                                       Color.TRANSPARENT       透明

  Color.GRAY        灰色                                       Color.WHITE                  白色

四、Bitmap  图像

自定义View类的更多相关文章

  1. 安卓开发28:自定义View类

    自定义View类 通过自定义View类,可以自定义复杂的,按照自己需求的控件. 一个简单的例子 mainActivity.java 这个里面就是最普通的代码,但是给自定义的控件加上了一个onclick ...

  2. Android自定义View之圆环交替 等待效果

    学习了前面两篇的知识,对于本篇实现的效果,相信大家都不会感觉太困难,我要实现的效果是什么样呢?下面请先看效果图: 看上去是不很炫的样子,它的实现上也不是很复杂,重点在与onDraw()方法的绘制. 首 ...

  3. Android之自定义View的实现

    对于学习Android开发的小童鞋对于自定义View一定不会陌生,相信大家对它是又爱又恨,爱它可以跟随我们的心意设计出漂亮的效果:恨它想要完全流畅掌握,需要一定的功夫.对于初学者来说确实很不容易,网上 ...

  4. Android自定义View自定义属性

    1.引言 对于自定义属性,大家肯定都不陌生,遵循以下几步,就可以实现: 自定义一个CustomView(extends View )类 编写values/attrs.xml,在其中编写styleabl ...

  5. Android自定义View

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24252901 很多的Android入门程序猿来说对于Android自定义View ...

  6. 自定义View(二)--继承自ViewGroup

    自定义View包括很多种,上一次随笔中的那一种是完全继承自View,这次写的这个小Demo是继承自ViewGroup的,主要是将自定义View继承自ViewGroup的这个流程来梳理一下,这次的Dem ...

  7. Android 自定义View修炼-自定义View-带百分比进度的圆形进度条(采用自定义属性)

    很多的时候,系统自带的View满足不了我们功能的需求,那么我们就需要自己来自定义一个能满足我们需求的View,自定义View我们需要先继承View,添加类的构造方法,重写父类View的一些方法,例如o ...

  8. Android 自定义View修炼-Android开发之自定义View开发及实例详解

    在开发Android应用的过程中,难免需要自定义View,其实自定义View不难,只要了解原理,实现起来就没有那么难. 其主要原理就是继承View,重写构造方法.onDraw,(onMeasure)等 ...

  9. 自定义view组件

    参考<疯狂android讲义>第2版 2.1节P48,对应CustomViewDemo.zip. 若在开发过程中,发现现有的view均不能满足需要,可以自定义一个view. 自定义一个vi ...

随机推荐

  1. 阿里云申请ssl证书

    申请证书(本文以阿里云服务器为背景,申请证书也以阿里云域名申请证书来作为实例) (1)登陆阿里云服务器,初次配置的用户,不建议直接搜索‘ssl证书’进行购买,因为这样购买后证书与域名对应的引导性并不强 ...

  2. WebService学习-第一弹

    一:WebService简介(1)简介----百度百科(注意标识的重点) Web service是一个平台独立的,低耦合的,自包含的.基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言 ...

  3. ionic3 npm install cordova error syscall rename

    突然出现cordova 不是内部或外部命令,也不是可运行的程序或批处理文件. 可是之前cordova安装后一直用的好好的啊,后来尝试重新安装cordova 出现这个错误.也尝试重新安装了最新版本的no ...

  4. android项目架构 -----Android 知识体系与常用第三方框架

    好东西值得分享 ,这是网络上总结的一些开源的东西直接就拿过来了  .... Android通用流行框架大全 先把这张图放在这 ,先来谈一谈项目结构 .我喜欢将东西按模块来划分: 都知道module . ...

  5. salesforce零基础学习(九十二)使用Ant Migration Tool 实现Metadata迁移

    我们在做项目时经常会使用changeset作为部署工具,但是某些场景使用changeset会比较难操作,比如当我们在sandbox将apex class更改名字想要部署到生产的org或者其他环境的or ...

  6. SpringBoot2.0源码分析(三):整合RabbitMQ分析

    SpringBoot具体整合rabbitMQ可参考:SpringBoot2.0应用(三):SpringBoot2.0整合RabbitMQ RabbitMQ自动注入 当项目中存在org.springfr ...

  7. 【MySQL经典案例分析】关于数据行溢出由浅至深的探讨

    本文由云+社区发表 一.从常见的报错说起 ​ 故事的开头我们先来看一个常见的sql报错信息: ​ 相信对于这类报错大家一定遇到过很多次了,特别对于OMG这种已内容生产为主要工作核心的BG,在内容线的存 ...

  8. 【Javascript系列】变量作用域

    问题描述 本篇文章主要讲解javascript变量及其作用域. 1   内容区 在js中,变量大致可分为全局变量(全局作用域)和局部变量(局部作用域): 用关键字var定义变量(全局变量,可以省略va ...

  9. UVC 驱动调用过程与驱动框架的简单分析

    内核:Linux-3.4.2 驱动:drivers\media\video\uvc\uvc_driver.c UVC 驱动整体调用流程: /* 打开设备描述符 */ 1. open: uvc_v4l2 ...

  10. NSOperation讲解

    本篇博客转自https://www.jianshu.com/p/4b1d77054b35 1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperat ...