Android的自定义视图

本文详细介绍了Android自定义视图的必经之路,包括自定义视图的基础方法、分类,以及测量、布局和绘制的过程。重点讲解了自定义视图的构造函数、属性配置、视图结构、坐标系、位置描述以及测量规格MeasureSpec的重要概念,帮助开发者掌握自定义视图的核心技巧。
摘要由CSDN通过智能技术生成

概述

安卓开发进阶的必经之路

为什么要自定义视图

自定义视图的基本方法

自定义查看的最基本的三个方法分别是:onMeasure(),onLayout(),onDraw(); 查看在活动中显示出来,要经历测量,布局和绘制三个步骤,分别对应三个动作:测量,布局和平局。

  • 测量:onMeasure()决定查看的大小;

  • 布局:onLayout()决定查看在一个ViewGroup中的位置;

  • 绘制:的onDraw()决定绘制这个视图。

自定义控件分类

  • 自定义查看:只需要重写onMeasure()和onDraw()

  • 自定义ViewGroup:则只需要重写onMeasure()和onLayout()

自定义视图基础

查看的分类

视图查看主要分为两类

类别 解释 特点
单一视图 即一个视图,如TextView的 不包含子视图
视图组 即多个视图组成的ViewGroup中,如的LinearLayout 包含子视图

查看类简介

  • 查看类是Android的中各种组件的基类,如视图是一个ViewGroup基类

  • 查看表现为显示在屏幕上的各种视图

安卓中的UI组件都由查看,ViewGroup中组成。

  • 查看的构造函数:共有4个

    //如果查看是在Java代码里面new的,则调用第一个构造函数public CarsonViewContext context){
        supercontext);   } //如果视图是在.XML里声明的,则调用第二个构造函数//自定义属性是从AttributeSet中参数传进来的公共CarsonView语境上下文AttributeSet中ATTRS){ 超级上下文ATTRS);   } //不会自动调用//一般是在第二个构造函数里主动调用//如查看有风格属性时公开CarsonView上下文语境,
    
           
    
    
    
    
          
           
    
    
    
    
    
          AttributeSet attrsint defStyleAttr){ supercontextattrsdefStyleAttr);   } // API21之后才使用//不会自动调用//一般是在第二个构造函数里主动调用//如查看有风格属性时公开CarsonView上下文语境AttributeSet中的ATTRSINT defStyleAttrINT defStyleRes) {
        supercontextattrsdefStyleAttrdefStyleRes);
           
    
    
       
       
       
       
          
           
      }public CarsonViewContext context){
       supercontext);   } //如果视图是在.XML里声明的,则调用第二个构造函数//自定义属性是从AttributeSet中参数传进来的公共CarsonView语境上下文AttributeSet中ATTRS){ 超级上下文ATTRS);   } //不会自动调用//一般是在第二个构造函数里主动调用//如查看有风格属性时公开CarsonView上下文语境,
    
           
    
    
    
    
          
           
    
    
    
    
    
          AttributeSet attrsint defStyleAttr){ supercontextattrsdefStyleAttr);   } // API21之后才使用//不会自动调用//一般是在第二个构造函数里主动调用//如查看有风格属性时公开CarsonView上下文语境AttributeSet中的ATTRSINT defStyleAttrINT defStyleRes) {
       supercontextattrsdefStyleAttrdefStyleRes);
           
    
    
       
       
       
       
          
           
      }

AttributeSet中的与自定义属性

 系统自带的浏览可以在XML中配置属性,对于写的好的自定义视图同样可以在XML中配置属性,为了使自定义的视图的属性可以在XML中配置,需要以下4个步骤:

  1. 通过为自定义视图添加属性<declare-styleable>

  2. 在XML中为相应的属性声明属性值

  3. 在运行时(一般为构造函数)获取属性值

  4. 将获取到的属性值应用到景观

查看视图结构

  1. PhoneWindow是Android的系统中最基本的窗口系统,继承自视窗类,负责管理界面显示以及事件响应。它是活动与景观系统交互的接口

  2. DecorView是PhoneWindow中的起始节点观,继承于视图类,作为整个视图容器来使用。用于设置窗口属性。它本质上是一个的FrameLayout

  3. 的ViewRoot在Activtiy启动时创建,负责管理,布局,渲染窗口UI等等

对于多视图的视图,结构是树形结构:最顶层是一个ViewGroup的ViewGroup以及下可能有多个ViewGroup中或查看,如下图:

一定要记住:无论是测量过程,布局过程还是绘制过程,永远都是从搜索树的根节点开始测量或计算(即从树的顶端开始),一层一层,一个分支一个分支地进行(即树形递归),最终计算整个景观树中各个视图,最终确定整个景观树的相关属性。

Android的坐标系

安卓的坐标系定义为:

  • 屏幕的左上角为坐标原点

  • 向右为X轴增大方向

  • 向下为ÿ轴增大方向

区别于一般的数学坐标系

查看位置(坐标)描述

查看的位置由4个顶点决定的4个顶点的位置描述分别由4个值决定:

请记住:查看的位置是相对于父控件而言的)

  • 上图:子视图上边界到父视图上边界的距离

  • 左:子视图左边界到父视图左边界的距离

  • 下图:子视图下边距到父视图上边界的距离

  • 右:子查看右边界到父视图左边界的距离

位置获取方式

查看的位置是通过view.getxxx()函数进行获取:(以最为例)

 
public final int getTop(){   return mTop ;  }   //其余如下:getLeft();      //获取子查看左上角距父查看左侧的距离getBottom();    //获取子查看右下角距父查看顶部的距离getRight();     //获取子视图右下角距父视图左侧的距离
    



 
 
 

与MotionEvent中get()和getRaw()的区别

// get():触摸点相对于其所所组件坐标系的坐标事件getX();       事件的getY(); // getRaw():触摸点相对于屏幕默认坐标系的坐标事件getRawX();    事件getRawY();





事件getX();       事件的getY(); // getRaw():触摸点相对于屏幕默认坐标系的坐标事件getRawX();    事件getRawY();





安卓中颜色相关内容

Android的支持的颜色模式:以ARGB8888为例介绍颜色定义:

查看树的绘制流程

查看树的绘制流程是谁负责的?

视图树的绘制流程是通过的ViewRoot去负责绘制的,的ViewRoot这个类的命名有点坑,最初看到这个名字,翻译过来是视图的根节点,但是事实完全不是这样,的ViewRoot其实不是查看的根节点,它连视图节点都算不上,它的主要作用是查看树的管理者,负责将DecorView和PhoneWindow“组合”起来,而查看树的根节点严格意义上来说只有DecorView;每个DecorView都有一个的ViewRoot与之关联,这种关联关系是由窗口管理去进行管理的;

观点的添加

 

查看的绘制流程

 

测量

  1. 系统为什么要有措施过程?

  2. 测量过程都干了点什么事?

  3. 对于自适应的尺寸机制,如何合理的测量一颗景观树?

  4. 那么ViewGroup中是如何向子查看传递限制信息的?

  5. 滚动型嵌套的ListView问题?

 

布局

  1. 系统为什么要有布局过程?

  2. 布局过程都干了点什么事?

 

  1. 系统为什么要有画过程?

  2. 绘制过程都干了点什么事?

 

的LayoutParams

ayoutParams翻译过来就是布局参数,子视图通过的LayoutParams告诉父容器(ViewGroup中)应该如何放置自己。从这个定义中也可以看出来的LayoutParams与ViewGroup中是息息相关的,因此脱离的ViewGroup谈的LayoutParams是没有意义的。

事实上,每个的ViewGroup的子类都有自己对应的的LayoutParams类,典型的如LinearLayout.LayoutParams和FrameLayout.LayoutParams等,可以看出来的LayoutParams都是对应的ViewGroup子类的内部类

MarginLayoutParams

MarginLayoutParams是和外间距有关的。事实也确实如此,和的LayoutParams相比,MarginLayoutParams只是增加了对上下左右外间距的支持。实际上大部分的LayoutParams的实现类都是继承自MarginLayoutParams,因为基本所有的父容器都是支持子视图设置外间距的

  • 属性优先级问题MarginLayoutParams主要就是增加了上下左右4种外间距在构造方法中,先是获取了余量属性;如果该值不合法,就获取horizo​​ntalMargin;如果该值不合法,再去获取LEFTMARGIN和rightMargin属性(verti

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值