欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

View基础调用和接口记录

程序员文章站 2022-03-05 14:24:42
View相关方法记录,自定义之前的预热,大概了解一下View...

基础

API

构造方法

  1. new 创建的构造方法
    public CanvasTestView(Context context) {
        super(context);
    }
  1. XML 内构造方法-自定义属性 - attrs
    public CanvasTestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
AttributeSet attrs 是指自定义参数
  1. XML 内 新增设置Style - defStyleAttr
    public CanvasTestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
  1. Theme 内设置的Style - defStyleRes
    public CanvasTestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

用途

尺寸测量,通过参数决定我们的自定义View用的宽和高是多少

参数

int widthMeasureSpec int heightMeasureSpec

google实现的是:
int类型的32位二进制位中,31-30这两位表示模式,0~29这三十位表示宽和高的实际值

取出的方法已经被封装好,直接调用即可,

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

布局模式

  1. UNSPECIFIED
    二进制表示:00
    父容器没有对当前View有任何限制,当前View可以任意取尺寸

  2. EXACTLY
    二进制表示:01
    当前的尺寸就是当前View应该取的尺寸

  3. AT_MOST
    二进制表示:10
    当前尺寸是当前View能取的最大尺寸

对应数值

import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.UNSPECIFIED;

 UNSPECIFIED ===0
 EXACTLY ===1073741824
 AT_MOST ===-2147483648

经过测试发现:
EXACTLY对应match_parent定值(100dp),无论XML设置值的大小
AT_MOST对应wrap_content

宽和高的实际值

宽和高的实际值,单位是px
宽和高的实际值 = XML内尺寸(dp)* 屏幕密度

有的车机在XML内部直接使用的就是px,实际尺寸就会等于XML内尺寸

屏幕密度:

        DisplayMetrics displayMetrics =getResources().getDisplayMetrics();
        LogUtils.i(TAG, "displayMetrics.density ===" + displayMetrics.density);

void onDraw(Canvas canvas)

核心

View绘制的核心,需要绘制的内容都会绘制在Canvas

super.onDraw(canvas) 法来实现基本的绘制功能(绘制背景颜色、背景图片),
要想在这基础上进行实现自己的逻辑,可以在方法的前后添加代码,
在方法前添加的,就是绘制在原生 TextView 的底层,
在方法后添加的,就是绘制在原生 TextView 的上层

void onLayout(boolean changed, int left, int top, int right, int bottom)

用途

为View树计算实际的位置;当这个view和其子view被分配一个大小和位置时,被layout触发

参数

boolean changed :当前View的大小和位置改变了 int left :相较于父布局的原点,左部位置 int top :相较于父布局的原点,顶部位置 int right :相较于父布局的原点,右部位置 int bottom :相较于父布局的原点,下部位置

void onFinishInflate()

从XML加载组件后回调

void onSizeChanged(int w, int h, int oldw, int oldh)

调用顺序

onMeasure --> onLayout --> onDraw -->

API - 方法

void invalidate()

用途:

UI线程中使用
请求重绘( onDraw),同步方法,如果视图的大小发生了变化,还会调用 layout()方法,

关于 layout()方法的触发时机是在:
void invalidate(boolean invalidateCache)
-->
void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,boolean fullInvalidate)
-->
ViewGroup --> void invalidateChild(View child, final Rect dirty)
-->
parent.invalidateChildInParent(location, dirty) --> ViewParent invalidateChildInParent(final int[] location, final Rect dirty)

没有找到具体的位置,不过父布局确实有重绘的可能。

触发时机:

  1. 直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身,自定义的时候用的还挺多;
  2. 调用setSelection()方法,请求重新draw(),但只会绘制调用者本身;
  3. 调用setVisibility()方法,会间接调用invalidate()方法,继而绘制该View
  4. 调用setEnabled()方法,请求重新draw(),但不会重新绘制任何视图,包括调用者本身。

void postInvalidate()

线程中可用
请求重绘

void requestLayout()

对View树进行重新布局layout过程(包括measure()过程和layout()过程),不会调用draw()过程,即不会重新绘制任何视图,包括该调用者本身

boolean requestFocus()

请求View树的draw()过程,但只会绘制需要重绘的视图,即哪个View或ViewGroup调用了这个方法,就重绘哪个视图

参考和转载地址

手把手教你写一个完整的自定义View:https://www.jianshu.com/p/af266ff378c6

【Android - 自定义View】之自定义View浅析:https://www.cnblogs.com/itgungnir/p/6217447.html

本文地址:https://blog.csdn.net/weixin_35691921/article/details/110523313