2022-01-03

1.SurfaceView详解

2.双缓冲技术

3.如何去使用SurfaceView

# 二、自定义view

## 什么是自定义view:

主要是Andorid系统内置的View 无法实现我们的 需求,我们需要针对我们的业务需求定制我们想要的 View.自定义View 我们大部分时候只需重写两个函数: onMeasure(),onDraw(). onMeasure()负责对当前View 的尺寸进行测量,onDraw负责把当前这个View绘制出来,当然了,还需要写构造函数。

public Views(Context context) {

    super(context);

}

public Views(Context context,  AttributeSet attrs) {

    super(context, attrs);

}

# 三、如何实现自定义View?

## 三种方式:1. **组合控件** 、2 .自绘控件、3.  **继承控件**

![img](https://upload-images.jianshu.io/upload_images/10294405-49437ed26f19f7d5.png?imageMogr2/auto-orient/strip|imageView2/2/w/557/format/webp)

# 四、自定义View基础

## 4.1 分类

自定义View的实现方式有以下几种

| 类型              | 定义                                                        |

| ----------------- | ------------------------------------------------------------ |

| 自定义组合控件    | 多个控件组合成为一个新的控件,方便多处复用                  |

| 继承系统View控件  | 继承自TextView等系统控件,在系统控件的基础功能上进行扩展    |

| 继承View          | 不复用系统控件逻辑,继承View进行功能定义                    |

| 继承系统ViewGroup | 继承自LinearLayout等系统控件,在系统控件的基础功能上进行扩展 |

| 继承ViewViewGroup | 不复用系统控件逻辑,继承ViewGroup进行功能定义                |

## 4.2 View绘制流程

View的绘制基本由measure()、layout()、draw()这个三个函数完成

| 函数      | 作用                        | 相关方法                                    |

| --------- | ---------------------------- | -------------------------------------------- |

| measure() | 测量View的宽高              | measure(),setMeasuredDimension(),onMeasure() |

| layout()  | 计算当前View以及子View的位置 | layout(),onLayout(),setFrame()              |

| draw()    | 视图的绘制工作              | draw(),onDraw()                              |

## 4.3 坐标系

在Android坐标系中,以屏幕左上角作为原点,这个原点向右是X轴的正轴,向下是Y轴正轴。如下所示:

![img](https://upload-images.jianshu.io/upload_images/10294405-a57f0f703dca0eb4.png?imageMogr2/auto-orient/strip|imageView2/2/w/491/format/webp)

除了Android坐标系,还存在View坐标系,View坐标系内部关系如图所示。

![img](https://upload-images.jianshu.io/upload_images/10294405-4ca426e6a92db696.png?imageMogr2/auto-orient/strip|imageView2/2/w/1200/format/webp)

## 4.4 View获取自身高度

由上图可算出View的高度:

- width = getRight() -  getLeft();

- height  =  getBottom()  -  getTop();

View的源码当中提供了getWidth()和getHeight()方法用来获取View的宽度和高度,其内部方法和上文所示是相同的,我们可以直接调用来获取View得宽高。

## 4.5 View自身的坐标

通过如下方法可以获取View到其父控件的距离。

```

getTop();获取View到其父布局顶边的距离。

getLeft();获取View到其父布局左边的距离。

getBottom();获取View到其父布局顶边的距离。

getRight();获取View到其父布局左边的距离。

```

## 4.6 构造函数

无论是我们继承系统View还是直接继承View,都需要对构造函数进行重写,构造函数有多个,至少要重写其中一个才行。如我们新建`TestView`,

```java

public class TestView extends View {

    /**

    * 在java代码里new的时候会用到

    * @param context

    */

    public TestView(Context context) {

        super(context);

    }

    /**

    * 在xml布局文件中使用时自动调用

    * @param context

    */

    public TestView(Context context, @Nullable AttributeSet attrs) {

        super(context, attrs);

    }

    /**

    * 不会自动调用,如果有默认style时,在第二个构造函数中调用

    * @param context

    * @param attrs

    * @param defStyleAttr

    */

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

        super(context, attrs, defStyleAttr);

    }

    /**

    * 只有在API版本>21时才会用到

    * 不会自动调用,如果有默认style时,在第二个构造函数中调用

    * @param context

    * @param attrs

    * @param defStyleAttr

    * @param defStyleRes

    */

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {

        super(context, attrs, defStyleAttr, defStyleRes);

    }

}

```

## 4.7 自定义属性

Android系统的控件以android开头的都是系统自带的属性。为了方便配置自定义View的属性,我们也可以自定义属性值。

Android自定义属性可分为以下几步:

```

1.自定义一个View

2.编写values/attrs.xml,在其中编写styleable和item等标签元素

3.在布局文件中View使用自定义的属性(注意namespace)

4.在View的构造方法中通过TypedArray获取

```

## 4.8 实例说明

自定义属性的声明文件

```xml

   

   

       

           

           

       

   

```

自定义View类

```java

public class MyTextView extends View {

    private static final String TAG = MyTextView.class.getSimpleName();

    //在View的构造方法中通过TypedArray获取

    public MyTextView(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();

    }

}

```

布局文件中使用

```xml

    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" >

   

        android:layout_width="100dp"

        android:layout_height="200dp"

        app:testAttr="520"

        app:text="helloworld" />

```

## 4.9 属性值的类型format

###  (1). reference:参考某一资源ID

* 属性定义

```xml

   

```

* 属性使用

```xml

```

###  (2).  color:颜色值

* 属性定义:

```xml

```

* 属性使用 :

```xml

```

(3). boolean:布尔值

- 属性定义:

```xml

```

- 属性使用:

```xml

你可能感兴趣的:(2022-01-03)