自定义View

在Android平台打造优美的控件

Posted by wushiqian on August 18, 2019

自定义View

自定义View

继承系统控件的自定义View

继承View的自定义View

​ 从上一篇文章知道自定义view需要对wrap_content属性进行处理 ​ 修改布局文件,让RectView的宽度分别为wrap_content和match_parent效果都是一样的:

@Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
      int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
      int widthSpecSize=MeasureSpec.getSize(widthMeasureSpec);
      int heightSpecSize=MeasureSpec.getSize(heightMeasureSpec);
      if(widthSpecMode==MeasureSpec.AT_MOST&&heightSpecMode==MeasureSpec.AT_MOST){
          setMeasuredDimension(400,400);
      }else if(widthSpecMode==MeasureSpec.AT_MOST){
          setMeasuredDimension(400,heightSpecSize);
      }else if(heightSpecMode==MeasureSpec.AT_MOST){
          setMeasuredDimension(widthSpecSize,400);
      }
  }

自定义属性

​ 首先在values目录下创建 attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RectView">
        <attr name="rect_color" format="color" />
    </declare-styleable>
</resources>

​ 这个配置文件定义了名为RectView的自定义属性组合,我们定义了rect_color属性,它的格式为color,接下来在RectView的构造函数中解析自定义属性的值:

public RectView(Context context, AttributeSet attrs) {
       super(context, attrs);
       TypedArray mTypedArray=context.obtainStyledAttributes(attrs,R.styleable.RectView);
       //提取RectView属性集合的rect_color属性,如果没设置默认值为Color.RED
       mColor=mTypedArray.getColor(R.styleable.RectView_rect_color,Color.RED);
       //获取资源后要及时回收
       mTypedArray.recycle();
       initDraw();
   }

自定义组合控件

常见例子:自定义标题栏

自定义ViewGroup

继承ViewGroup

对wrap_content属性进行处理

重写onMeasure方法

重写onLayout方法

处理滑动冲突

分两种情况进行处理

  • 外部的滑动与内部的滑动方向不一样
  • 外部的滑动与内部的滑动方向一样

不一样比较好处理,我们主要看一下不一样的情况,我们可以使用外部处理或内部处理。

弹性滑动到其他页面

快速滑动到其他页面

再次触摸屏幕阻止页面继续滑动

自定义绘制知识的四个级别

  • Canvas 的 drawXXX() 系列方法及 Paint 最常见的使用
  • Paint 的完全攻略
  • Canvas 对绘制的辅助——范围裁切和几何变换。
  • 使用不同的绘制方法来控制绘制顺序

Canvas.drawXXX() 和 Paint 基础

Canvas官方文档

Paint官方文档

Paint

Paint 的 API 大致可以分为 4 类:

  • 颜色
  • 效果
  • drawText() 相关
  • 初始化

drawText()文字的绘制

Canvas 对绘制的辅助 clipXXX() 和 Matrix

绘制顺序

属性动画

硬件加速

​ 所谓硬件加速,指的是把某些计算工作交给专门的硬件来做,而不是和普通的计算工作一样交给 CPU 来处理。这样不仅减轻了 CPU 的压力,而且由于有了「专人」的处理,这份计算工作的速度也被加快了。这就是「硬件加速」。

​ 而对于 Android 来说,硬件加速有它专属的意思:在 Android 里,硬件加速专指把 View 中绘制的计算工作交给 GPU 来处理。进一步地再明确一下,这个「绘制的计算工作」指的就是把绘制方法中的那些 Canvas.drawXXX() 变成实际的像素这件事。

布局过程的自定义

重写 onMeasure() 来全新定制自定义 View 的尺寸

重写 onMeasure() 和 onLayout() 来定制 Layout 的内部布局

触摸反馈

  1. 重写 onTouchEvent(),在里面写上你的触摸反馈算法,并返回 true(关键是 ACTION_DOWN 事件时返回 true)。

  2. 如果是会发生触摸冲突的 ViewGroup,还需要重写 onInterceptTouchEvent(),在事件流开始时返回 false,并在确认接管事件流时返回一次 true,以实现对事件的拦截。

  3. 当子 View 临时需要组织父 View 拦截事件流时,可以调用父 View 的 requestDisallowInterceptTouchEvent() ,通知父 View 在当前事件流中不再尝试通过 onInterceptTouchEvent() 来拦截。

自定义View的例子

侧滑删除

一款你不可错过的可爱 & 小资风格的加载等待自定义View

一个简单 & 好用的搜索框(含历史搜索记录)