1. 自定义view的基本方法:
2. View分类:
3. 自定义控件分类:
4. View类:
//如果View是Java代码里new的,则调用第一个构造函数
public CarsonView(Context context){
super(context);
}
// 如果View是在.xml里声明的,则调用第二个构造函数
// 自定义属性是从AttributeSet参数传进来的
public CarsonView(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 不会自动调用
// 一般是在第二个构造函数里主动调用
// 如View有style属性时
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
//API21之后才使用
// 不会自动调用
// 一般是在第二个构造函数里主动调用
// 如View有style属性时
public CarsonView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
5. AttributeSet与自定义属性 :
系统自带的View可以在xml中配置属性,对于写的好的自定义View同样可以在xml中配置属性,为了使自定义的 View的属性可以在xml中配置,需要以下4个步骤:
通过 为自定义View添加属性
在xml中为相应的属性声明属性值
在运行时(一般为构造函数)获取属性值
将获取到的属性值应用到View
自定义属性的声明文件—value/attrs.xml文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="test">
<attr name="text" format="string" />
<attr name="testAttr" format="integer" />
</declare-styleable>
</resources>
public class NewTextView extends View {
private static final String TAG = NewTextView.class.getSimpleName();
//在View的构造方法中通过TypedArray获取
public NewTextView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test);
String text = ta.getString(R.styleable.test_testAttr);
int textAttr = ta.getInteger(R.styleable.test_text, -1);
Log.e(TAG, "text = " + text + " , textAttr = " + textAttr);
ta.recycle();
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/com.example.test"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.test.NewTextView
android:layout_width="100dp"
android:layout_height="200dp"
app:testAttr="520"
app:text="helloworld" />
</RelativeLayout>
6. View视图结构:
PhoneWindow是Android系统中最基本的窗口系统,继承自Windows类,负责管理界面显示以及事件响应。它
是Activity与View系统交互的接口
DecorView是PhoneWindow中的起始节点View,继承于View类,作为整个视图容器来使用。用于设置窗口属
性。它本质上是一个FrameLayout
ViewRoot在Activtiy启动时创建,负责管理、布局、渲染窗口UI等等
注意!!! :
无论是measure过程、layout过程还是draw过程,永远都是从View树的根节点开始测量或计算(即从 树的顶端开始),一层一层、一个分支一个分支地进行(即树形递归),最终计算整个View树中各个View,最终确定整个View树的相关属性
7 坐标系:
Android坐标系:
view坐标系:
View的位置
getLeft(); //获取子View左上角距父View左侧的距离
getBottom(); //获取子View右下角距父View顶部的距离
getRight(); //获取子View右下角距父View左侧的距离
getTop(); //获取子View右下角距父View顶部的距离
触点MotionEvent的位置:
//get() :触摸点相对于其所在组件坐标系的坐标
event.getX();
event.getY();
//getRaw() :触摸点相对于屏幕默认坐标系的坐标
event.getRawX();
event.getRawY();
view树的绘制流程是通过ViewRoot去负责绘制的,ViewRoot其实不是View的根节点,它连view节点都算不上,它的主要作用 是View树的管理者,负责将DecorView和PhoneWindow“组合”起来,而View树的根节点严格意义上来说只有 DecorView;每个DecorView都有一个ViewRoot与之关联,这种关联关系是由WindowManager去进行管理的
具体的代码实现见下一篇博客:
每日一学——自定义View(具体实现代码)(二)