Android开发之自定义View

自定义控件

使用场景: 在实际开发中经常会遇到现有的UI控件不能满足项目需求,或一个功能涉及到多个UI控件的组合,或实现某一特效的UI,这时必须通过自定义View的方式,实现这些功能,例如股票的实时统计图、电子书等。

分类

绘制控件 - 自绘控件

1.继承View
需要自定义绘制内容,需要继承View,必须要重写onDraw方法,在onDraw方法中来进行绘制,实现onMeasure方法,来测量控件的空间。

2.继承ViewGroup

  • 通过在ViewGroup中通过this.addView(<控件对象>)来添加控件
  • onMeasure方法,来测量控件的空间
  • onLayout方法必须实现,在此方法中处理子控件的位置。当视图初始化,或者视图位置发生改变时候,调用此方法。

组合控件

通过继承系统已经存在的视图容器,在初始化时候,直接加载布局

mInflater.inflate(<布局资源的ID>,this);
mIvBack = (ImageView) findViewById(R.id.btn_back);

继承控件

通过继承系统已经存在的视图或者视图容器,在内部改变此视图或者视图容器的功能
例如:通过改变ListView添加删除功能

自定义View步骤

  • 创建类,继承View及View的子类,并提供相关的构造方法
  • 重写onMeasure()方法,并调用setMeasuredDimension(int width, int height)设置控件的大小
  • 重写onDraw()方法,实现绘制特定内容
  • 重写onTouchEvent()方式处理触摸事件
  • 在布局文件中使用<类全名>并设置属性

自定义View属性

1.位置:res/values/attrs.xml

2.属性集



    
    
        
        
        
    

3.指定属性名及其内容格式
例:

string 字符型
integer 整数型
dimension 尺寸值
color 颜色值
reference 参考某一资源ID
boolean:布尔值

使用自定义View属性

在布局控件标签中引用:xmlns:my="http://schemas.android.com/apk/res/{package_name}"
或xmlns:app="http://schemas.android.com/apk/res-auto"
在自定义控件中使用:my:text=““或app:text=""

在自定义View的View(Context context, AttributeSet attrs)构造方法中,获取自定义属性的值

//TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组
        //在使用完成后,一定要调用recycle方法
         TypedArray ta = context.obtainStyledAttributes(attrs,
                    R.styleable.LabelView);

            CharSequence s = ta.getString(R.styleable.LabelView_text);
            if (s != null) {
                setText(s.toString());
            }

            setTextColor(ta.getColor(R.styleable.LabelView_textColor, 0xFF000000));

            int textSize = ta.getDimensionPixelSize(R.styleable.LabelView_textSize, 0);
            if (textSize > 0) {
                setTextSize(textSize);
            }
            ta.recycle();

涉及相关类

View 类

  • View(Context) 动态实例化控件的构造方法
  • View(Context context, AttributeSet attrs) 布局中使用控件的构造的方法
  • onMeasure(int widthMeasureSpec, int heightMeasureSpec) 自定义控件时重写的方法,用于测量控件大小
  • onDraw(Canvas canvas) 在自义控件上绘制相关内容
  • onTouchEvent(MotionEvent) 实现触摸事件处理方法
  • setPadding(int l,int t,int r,int b) 设置内部间距
  • layout(int l, int t, int r,int b) 改变控件位置的方法
  • requestLayout() //清除布局,获取新的布局空间(刷新UI,重新调用onDraw()方法绘制UI)
  • invalidate() //重新绘制新的数据(刷新UI,重新调用onDraw()方法绘制UI)

MeasureSpec 测量空间工具类

  • int MeasureSpec.getMode(mSpec) 获取控件大小模式
    • MeasureSpec.EXACTLY,确切空间,布局中的属性值一般为match_parent或160dp固定值
    • MeasureSpec.AT_MOST 尽量多的空间,布局中的属性值wrap_content
    • MeasureSpec.UNSPECIFIED 未指定的,一般在父控件中使用
  • MeasureSpec.getSize(mSpec) 获取控件大小

TypedArray 属性数组类

  • TypeArray Context.obtainStyledAttributes(attrs,R.styleable.LabelView) 获取指定attrs中的所有属性
  • String getString(R.styleable.LabelView_text) 获取指定属性的文本值
  • int getDimensionPixelSize(R.styleable.LabelView_textSize, 0) 获取指定属性的间距值
  • int getColor(R.styleable.LabelView_textColor, 0xFF000000) 获取指定属性的颜色值

Paint 画笔类

  • Paint.setAntiAlias(true) 启用抗锯齿
  • Paint.setTextSize(int pixes) 设置字体大小,像素,一般转成sp
  • Paint.setColor(int color) 设置颜色
  • Paint.setStyle(Paint.Style) 设置画笔样式
  • float mTextPaint.measureText(String) 测量文字的大小
  • Paint.ascent() 获取文字基准线以上到文字顶部的间距,负数
  • Paint.descent() 获取文字基准线以下到文字底部的间距

Canvas 画布类

  • canvas.drawText(String,int x,int y,Paint) 绘制文本
  • canvas.drawRoundRect(RectF,int rx,int ry,Paint) 绘制圆角四边方形
  • canvas.drawBitmap(bitmap, left, top, paint) 绘制图片
  • canvas.drawCircle(cx, cy, radius, paint) 绘制圆
  • canvas.drawLine(startX, startY, stopX, stopY, paint) 绘制线条

Xfermode 两个图层的转换模式

Xfermode有三个子类 :
AvoidXfermode 指定了一个颜色和容差,强制Paint避免在它上面绘图(或者只在它上面绘图)。
PixelXorXfermode 当覆盖已有的颜色时,应用一个简单的像素异或操作。
PorterDuffXfermode 这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

Android开发之自定义View_第1张图片

要应用转换模式,可以使用setXferMode方法,如下所示:

AvoidXfermode avoid = new AvoidXfermode(Color.BLUE, 10, AvoidXfermode.Mode. AVOID);
borderPen.setXfermode(avoid);

PorterDuff.Mode为枚举类,一共有16个枚举值:

1.PorterDuff.Mode.CLEAR
所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
显示上层绘制图片
3.PorterDuff.Mode.DST
显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER
正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER
上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN
取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN
取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT
取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT
取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP
取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR
异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN
取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN
取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY
取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN
取两图层全部区域,交集部分变为透明色

你可能感兴趣的:(Android开发之自定义View)