自定义View-简单的实验
一. 自定义View的种类1. 继承原生控件或者布局2. 组合原生控件3. 继承View二. 简单的自定义View例子1. 基础搭建
创建一个类继承于View,在构造方法里面初始化画笔。
重写onDraw方法,在里面画圆。
在布局文件中加入CircleView。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687public class CircleView extends View { //画笔变量 Paint mPaint; /** * 构造方法 java代码new * @param context */ public CircleView(Context context) { super(context); ...
自定义View-支持wrap_content
一. 问题描述在使用自定义View时,View宽 / 高的 wrap_content 属性不起自身应有的作用,而且是起到与 match_parent相同作用。
wrap_content 与 match_parent 区别:
wrap_content:视图的宽/高被设定成刚好适应视图内容的最小尺寸。
match_parent:视图的宽/高被设置为充满整个父布局。
其实这里有两个问题:
问题1:wrap_content 属性不起自身应有的作用。
问题2:wrap_content起到与match_parent相同的作用。
二. 问题分析问题出现在View的宽 / 高设置,那我们直接来看自定义View绘制中第一步对View宽 / 高设置的过程:measure过程中的 onMeasure 方法。
1234567891011121314151617181920212223242526272829303132333435363738394041//设置View的宽/高protected void onMeasure(int widthMeasureSpec, int heightMe ...
自定义View-自定义View的细节问题
一. 前言1. 单一View需要重写的方法onDraw,在其中绘制View自身的内容。
2. 多个View,ViewGroup需要重写的方法onMeasure,测量;onLayout,确定位置;onDraw,绘制内容。
3. 自定义属性① 在 values 目录下创建自定义属性的xml文件。
② 在自定义View的构造方法中加载自定义的Xml文件并解析属性值。
③ 在布局文件中使用自定义属性值。
二. 支持特殊属性1. 支持 wrap_content如果不在onMeasure()中对wrap_content作特殊处理,那么wrap_content属性将失效,那么如何支持wrap_content属性呢?
具体原因请看:自定义View-支持wrap_content
2. 支持padding & margin如果不支持,那么padding和margin(ViewGroup情况)的属性将失效。
对于继承View的控件,padding是在draw()中处理。
对于继承ViewGroup的控件,padding和margin会直接影响measure和layout过程。
三. 多线程直 ...
自定义View-Draw过程
一. 前言1. 作用绘制 View视图。
二. 单一View的Draw过程1. 原理① View绘制自身,包括背景和内容。
② 绘制装饰,包括滚动指示器,滚动条和前景。
2. 过程123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138/** * 源码分析:draw() * 作用:根据给定的 Canvas 自动渲染 View(包括其所有子 View)。 * 绘制过程: * 1. 绘制view背景 * 2. 绘制view内容 ...
自定义View-Layout过程
一. 前言1. 作用计算View的位置,即计算View的四个顶点位置:left,top,right和bottom。
二. 单一View的Layout过程123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081/** * 源码分析:layout() * 作用:确定View本身的位置,即设置View本身的四个顶点位置 */ public void layout(int l, int t, int r, int b) { // 当前视图的四个顶点 int oldL = mLeft; int oldT = mTop; int oldB = mBottom; int oldR = mRight; // 1. 确定View的位置:setFra ...
自定义View-Measure过程
一. 前言1. 作用Measure过程用来测量View的宽度和高度。
2. 注意① 在某些情况下,需要多次测量Measure才能确定View的最终宽高
② 因此,在上述情况下,Measure过程后得到的宽高不准确。
③ 因此,建议在Layout过程中onLayout去获取最终的宽高。
二. 储备知识1. ViewGroup.LayoutParms类① 作用
布局参数类,指定View的宽度width和高度height等布局参数。
② 具体使用
参数
解释
match_parent
强制性使子视图的大小扩展至与父视图大小相等,不含padding
wrap_content
自适应大小,强制性使视图扩展以便显示其全部内容,含padding
具体的值
dp/px
2. MeasureSpecs类① 简介
测量规格类,测量View大小的依据。每个MeasureSpecs代表了一组宽高的测量规格。
宽测量规格 widthMeasureSpecs 和 高测量规格 heightMeasureSpecs。
② 组成
测量规格MeasureSpecs = 测量模式Mode + 测量大 ...
自定义View-DecorView创建&显示
一. DecorView的创建1. 创建Window抽象类的子类PhoneWindow类的实例对象
2.为PhoneWindow类对象设置WindowManager对象
3.为PhoneWindow类对象创建DecorView类对象(根据所选主题样式)
4. 为DecorView类对象中的content增加Activity中设置的布局文件
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116/** * 具体使用:Activity的setContentView() */ @Override public void onCreate(Bundle savedIn ...
自定义View-绘制流程概述
一. 前言从上面的内容我们知道,View的绘制流程开始于ViewRootImpl对象的performTraversals。一层一层从顶级View-DecorView的ViewGroup开始,一层一层从ViewGroup至子View遍历测绘。
即自上而下遍历,由父视图到子视图,每一个ViewGroup负责测绘它所有的子视图,而底层的View会负责绘制自身。
绘制的流程 = measure过程、layout过程、draw过程。
1234567891011121314/** * 源码分析:ViewRootImpl.performTraversals() */private void performTraversals() { // 1. 执行measure流程 // 内部会调用performMeasure() measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight); // 2. 执行layout流程 performLayout(lp, mWidth, mHeight); ...