ARM2022.7.25
自定义View(该部分仅通过View部分讲解一点知识)
- Android系统内置的view无法满足我们的需求
- onMeasure()对当前view的尺寸进行测量、onDraw()绘制、构造函数
- xml布局中:wrap_content包住内容;match_parent填充父布局给予的全部空间;具体尺寸:dp、sp
- onMeasure()函数原型 protected void onMeasure(int widthMeasureSpec, int hightMeasureSpec) 传入的两个参数分别代表宽、高,但是int有32位,前两位代表对应的测量模式、后30位代表尺寸大小。比如widthMeasureSpec,前两位代表宽的测量模式,后30位是宽的大小。 测量模式:区别不同的布局模式。
- 从int数据提取测量模式与尺寸? 用Android内置的MeasureSpec测量规格可获得 int widthMode = MeasureSpec.get(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec);
- 说明(了解) 对于View,MeasureSpec由父容器的MeasureSpec和自身LayoutParams。
- onDraw函数 在画板Canvas对象上进行绘制
- 自定义布局属性 需要在根标签(LinearLayout)重设置命名空间 命名空间:
- 名称随便取
- 命名空间后面取值是固定的:schemas.android.com/apk/res-aut… 在自定义View构造函数中有一个AttributeSet属性,提取布局中的属性
Android自定义View
ps:View主要实现onMeasure()和onDraw();ViewGroup主要实现onMeasure()和onLayout()
View
单一视图,即一个View View类是Android各个组件的基类,View表现为显示在屏幕上的各种视图
package com.example.zihuiview1;
import android.content.Context;
import android.util.AttributeSet;
public class CarsonView {
Context context;
AttributeSet attributeSet;
int defStyleAttr;
int defStyleRes;
//第一个构造函数
public CarsonView(Context context) {
this.context = context;
}
//如果View是在xml布局中声明的话,调用第二个构造函数
//自定义属性是从AttributeSet参数传进来
//这个参数一般是必须重写,因为在LayoutInfaltor中CreateView,系统会通过反射调用该构造函数
//不重写会报错
public CarsonView(Context context, AttributeSet attributeSet) {
this.context = context;
this.attributeSet = attributeSet;
}
//不会自动调用
//一般是在第二个构造函数中调用第三个构造函数
//View有style属性时
public CarsonView(Context context, AttributeSet attributeSet, int defStyleAttr) {
this.context = context;
this.attributeSet = attributeSet;
this.defStyleAttr = defStyleAttr;
}
//不会自动调用
//一般是在第二个构造函数中主动调用
//API21后使用
//View有style属性时
public CarsonView(Context context, AttributeSet attributeSet, int defStyleAttr, int defStyleRes) {
this.context = context;
this.attributeSet = attributeSet;
this.defStyleAttr = defStyleAttr;
this.defStyleRes = defStyleRes;
}
}
View视图结构
- PhoneWindow是安卓系统中最基本的窗口系统,继承于Window类,负责管理系统显示以及事物响应。它是Activity与View系统交互的接口
- DecorView是PhoneWindow中的起始节点View,继承于View类,是整个视图的容易,用于设置窗口属性。
- ViewRoot是在Activity启动时创建,负责管理、布局、渲染窗口UI等。
- view树的绘制过程 答:由viewroot负责绘制,主要作用是View树的管理者,负责将DecorView和PhoneWindow"组合"起来。而View树的根节点严格来说只有DecorView,每一个DecorView都有ViewRoot与之关联,这种关联被WindowManager管理。
- View的添加
- View的绘制流程
Android坐标系 往右为x轴正方向,往下为y轴正方向 View位置描述 四个顶点决定,View的位置是相对于父控件而言的!! Top:子View上边界到达父View上边界的距离 Left:左到左 Bottom:下到上 Right:右到左
位置的获取方式
getLeft();//获取View左上角据父View左侧距离
//在MotionEvent中get()和getRaw()的区别
event.getX();
event.getRawX();
getMeasureWidth()和getWidth()区别(重点:面试会被问到getMeasureWidth()的底层逻辑及相关) getMeasureWidth()
- 在measure()过程结束后获得对应的值
- 通过setMeasuredDimension()方法进行设置 getWidth()
- 在layout()过程结束后获得对应的值;
- 通过视图右边的坐标减去左边的坐标计算出对应的值;
LayoutParams布局参数
- 子View通过该参数告诉父容器ViewGroup如何放置自己
- 每一个ViewGroup的子类都有自己对应的LayoutParams类 eg.LinearLayout.LayoutParams
MarginLayoutParams
- 与外边距有关,比LayoutParams增加了上下左右边距的支持
- margin>horizontalMargin和verticalMargin>leftMargin和RightMargin、topMargin和bottomMargin 构造函数,不合法就顺移
ViewGroup
视图组,即多个View组成的ViewFroup,eg.LinearLayout
自定义View的三种方法及自定义属性使用
三种方法:组合控件、继承控件、自绘控件
组合控件(相对简单)
讲系统原有控件进行组合,构成一个新空间
继承控件
适用:在原有系统控件基础上做一些修饰性的修改,而不是大幅度的改变 View、ViewGroup
自绘控件
复杂,所有的绘制逻辑和流程需要自己完成。 若最终为叶子控件,那么直接继承View,若最终为容器控件,那么直接继承ViewGroup。
自定义View中使用自定义属性
在values中编写需要的属性(res/values/下新建资源文件 attrs.xml)
- name :名字
- format: 属性格式 ps:自定义属性集合中包含多个自定义属性
1 <!--1.reference:参考某一资源ID-->
2 <ImageView android:background = "@drawable/图片ID"/>
3 <!--2. color:颜色值-->
4 <TextView android:textColor = "#00FF00"/>
5 <!--3.boolean:布尔值-->
6 <Button android:focusable = "true"/>
7 <!--4.dimension:尺寸值-->
8 <Button android:layout_width = "42dp"/>
9 <!--5. float:浮点值-->
10 <alpha android:fromAlpha = "1.0"/>
11 <!--6.integer:整型值-->
12 <TextView android:lines="1"/>
13 <!--7.string:字符串-->
14 <TextView android:text = "我是文本"/>
15 <!--8.fraction:百分数-->
16 <rotate android:pivotX = "200%"/>
17 <!--9.enum:枚举值-->
18 <LinearLayout
19 android:orientation = "vertical">
20 </LinearLayout>
21 <!--10.flag:位或运算-->
22 <TextView android:gravity="bottom|left"/>
23 <!--11.混合类型:属性定义时可以指定多种类型值-->
24 <ImageView android:background = "@drawable/图片ID" />
25 <!--或者-->
26 <ImageView android:background = "#00FF00" />