Android View解析

一、什么是View?

1.View是用户接口组件的基本构建块;

2.View在屏幕上占据一个矩形区域;

3.View通过绘制自己与事件处理两种方式与用户交互

设计View,主要是为了让应用能够与用户交互,要想完成交互,这个View就要在屏幕上占据一个矩形区域,然后利用这块屏幕区域与用户交互,交互的方式就两种,绘制自己与事件处理。

二、如何管理View?

Google的解决方案是:首先,一套完整的用户界面用一个Window来表示,Window首先加载一个超级复合View,用它来包含住所有的其他View,这个超级复合View就叫做DecorView

不同的View为了完成自己的交互任务所需要的屏幕区域大小是不同的,所以DecorView在确定给每个View分配的屏幕区域大小时,是允许View参与进来,与它一起商量的。但是每个View在屏幕区域中的位置就不能让View自己来决定了,而是由DecorView一手操办。

Activity中window和decorview的加载流程:

  • Activity管理着Window,Window管理着DecorView,Activity间接管理着DecorView
  • Activity处在“create"状态的时候创建对应的Window,并在setContentView里创建 DecorView,最终添加自定义布局到DecorView里。此时,Activity创建完毕,Window创建完毕,DecorView创建完毕,ViewTree构建成功,三者关系已建立。
  • Acitivity处在“resume"状态的时候,通过Window的管理类将DecorView添加到Window里,并提交更新DecorView的请求。当下次屏幕刷新信号到来之时,执行ViewTree三大流程(测量,布局,绘制),最终的效果就是我们的自定义布局显示在屏幕上。 “注”:指的状态执行时机是处在ActivityThread里的。
  • Android View解析_第1张图片

2.1 确定每个View的位置

虽然View无法决定自己在ViewGroup中的位置,但是开发者在使用View时,可以向ViewGroup表达自己所用的View要放在哪里。(xml 布局文件)

2.2 确定View大小

        2.2.1  开发者向ViewGroup表达的,我这个View需要的大小是多少;

        2.2.2  ViewGroup收到了开发者对View大小的说明,然后ViewGroup会综合考虑自己的空间大小以及开发者的请求,然后生成两个MeasureSpec对象(width与height)传给View,这两个对象是ViewGroup向子View提出的要求;两个对象将会传到子View的protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法中

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int desiredWidth = // 计算所需宽度;
    int desiredHeight = // 计算所需高度;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width, height;

    if (widthMode == MeasureSpec.EXACTLY) {
        // 确切的宽度
        width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
        // 宽度不超过所需尺寸
        width = Math.min(desiredWidth, widthSize);
    } else {
        // 未指定宽度
        width = desiredWidth;
    }

    if (heightMode == MeasureSpec.EXACTLY) {
        // 确切的高度
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        // 高度不超过所需尺寸
        height = Math.min(desiredHeight, heightSize);
    } else {
        // 未指定高度
        height = desiredHeight;
    }

    setMeasuredDimension(width, height);
}

其中莫得还有第三种标志位:UNSPECIFIED 它表示,你自己看着办,把你最理想的大小告诉我,我考虑考虑

三、自定义View

3.1 什么是自定义View

自定义View是Android开发中的重要概念,允许你创建不同于标准UI组件的用户界面元素。这些自定义View可以是各种形状、颜色和交互方式,完全满足你的设计需求。

3.2 创建自定义View

步骤1: 继承View类或其子类

要创建自定义View,首先需要继承自Android的View类或其子类,如ViewGroup。根据需要,你还可以继承更具体的子类,如TextViewImageView等实现自定义控件。以下是一个简单的示例:

public class MyCustomView extends View {
    public MyCustomView(Context context) {
        super(context);
    }
}

步骤2: 重写onMeasure方法

你需要重写onMeasure方法来定义自定义View的尺寸。这个方法决定了View的宽度和高度,通常基于View的内容和布局需求计算测量值。如上2.2代码

步骤3: 重写onDraw方法

onDraw方法用于绘制自定义View的内容。在这里,你可以使用Canvas对象进行绘制操作,包括绘制形状、文本、位图等。

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // 绘制自定义UI
    Paint paint = new Paint();
    paint.setColor(Color.RED);
    canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}

步骤4: 在XML布局中使用自定义View

步骤5: 在Java代码中操作自定义View

3.3 优化方向

3.3.1 使用硬件加速

3.3.2 避免不必要的绘制

3.3.3 使用合适的绘制方法 drawPath,drawBitmap

3.3.4 处理触摸事件:如果需要自定义View响应触摸事件,可以重写onTouchEvent方法,处理触摸事件逻辑。

3.3.5 多线程优化


你可能感兴趣的:(Android,UI,android)