view-View基础重认识

前言

android中的View形形色色,我们刚开始接触Android的时候就开始于它打交道了,但View以及与View相关的周边的知识点也是非常的繁多,并且从初级到高级我们都有很多可以学习的地方。我所知道的讲解View最全的应该是启航的Android自定义控件三部曲,非常面干货,在看人家博客的同时,我们也需要自己掌握相关知识。对于View我会根据我的理解以及看过的书和博客整理出View系列文章,从这里开始View之旅吧!

View的构造方法

我们使用的控件,都直接或间接的继承View,控件的使用有的是在xml里面有的是使用new的方式创建,所以我们先看看View的构造方法什么时候调用。

View的构造方法4个:

  • 方法一 是在Code中New 这个View的时候调用
  • 方法二 如果要在xml文件中使用,那么自定义的View得实现的方法,没有设置attrs,默认为null
  • 方法三和方法四在自定义View中可根据自己需要实现,但方法四实现需要最小Api为21
public View(Context context){
} 
public View(Context context, @Nullable AttributeSet attrs){
}
public View(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

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

}

这里说一下构造方法中AttributeSet,defStyleAttr,defStyleRes这三个参数;
AttributeSet: 用于资源分析,接收xml中定义的属性信息,比如我们TextView默认字体大小,就是用AttributeSet取到的,因此我们可以自己实现修改TextView等默认属性。当我们不实现AttributeSet就默认使用父类的,

  TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.MyView);             
        int textColor = a.getColor(R.styleable.MyView_textColor,0XFFFFFFFF);  
        float textSize = a.getDimension(R.styleable.MyView_textSize, 36);  

defStyleAttrdefStyleRes都是设置自定义属性,只是他们有一定的优先级,
在AppTheme中设置默认样式defStyleAttr的同时,在自定义View中也设置defStyleRes,默然情况下优先级:defStyleAttr > defStyleRes,也就是说只有在defStyleAttr为0的情况下,系统才会读取defStyleRes的值。
在整个自定义View设置属性的优先级为:xml > style > defStyleAttr > defStyleRes > theme

View的位置参数

View的参数位置只是做一个记录,经常使用肯定会知道,本来是想在processon上自己画图,画了会感觉里面基础图形很不友好,并且箭头动不动就弯曲,不好用,求推荐好用的画图工具。

View的坐标系,起始点为左上角x,y:(0,0)往左边X轴逐渐增大,往下边Y轴逐渐增大。如果当前屏幕大小为1080*1920,那么右下角的坐标为(1080,1920)。

下面坐标获取的Api来自两个类,上面一类来自View,如 getTop() getBottom() getLeft() getRight()
下面一类是来自MotionEvent类在实现onTouchEvent等触摸方法里面得到参数。如event.getRawX() event.getRawY()

在这里插入图片描述

  • getX() getY()是指:这个是android 3.0中View增加的,是指点击位置距离控件左上角的距离,如多点击的刚好是左上角那么得到的就是(0,0)
  • getTranslationX() getTranslationY()是指View左上角相对于父容器的偏移量,默认值为0.
  • 还有一个公式,getX()=getLeft+getTranslationX();
  • getY()=getTop+getTranslationY();

要知道View和MotionEvent都有getX()和getY()这个方法,MotionEvent的getX() getY()是指:手指触摸点距离当前View左上角的x和y坐标。

在这里插入图片描述
上面的Api方法来自MotionEvent类,在实现onTouchEvent等触摸方法里面得到参数。

  • event.getRawX() event.getRawY()这个算一组,获取的是相对手机屏幕左上角x和y的坐标
  • event.getX() event.getY()算一组,获取的是手指触摸点距离当前View左上角的x和y坐标

坐标实战

在这里我们要实现一个View,使用手可以拖动着滑动,我们用到上面的左边来实现

我们分别用getX() getY()和getRawX getRawY实现

    int lastX = 0;
    int lastY = 0;

 @Override
    public boolean onTouchEvent(MotionEvent event) {
    	//View相对于父容器左上角的坐标
        int x = (int) event.getX();
        int y = (int) event.getY();
		
        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                lastX = x;
                lastY = y;
                break;

            case MotionEvent.ACTION_MOVE:
                //每次移动的过程中x y的值都在更新,跟新后的值减去
                int offsetX = x - lastX;
                int offsetY = y - lastY;
                layout(getLeft()+offsetX,getTop()+offsetY,getRight()+offsetX,getBottom()+offsetY);
                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }

主要是记录点击的地方移动的位置,然后再移动的时候加上移动的距离就好了。

	 int lastX = 0;
    int lastY = 0;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    //获取的是相对手机屏幕左上角x和y的坐标
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                lastX = rawX;
                lastY = rawY;
                break;

            case MotionEvent.ACTION_MOVE:

                int offsetX = rawX - lastX;
                int offsetY = rawY - lastY;
                layout(getLeft() + offsetX, getTop() + offsetY, getRight() + offsetX, getBottom() + offsetY);
                lastX = rawX;
                lastY = rawY;

                break;
            case MotionEvent.ACTION_UP:

                break;
        }
        return true;
    }

View的相关方法

方法名称方法作用
View(Context context)View的构造方法,当在Code中创建或在XML中使用时调用
onMeasure(int, int)View测量方法,用于计算View的大小
onLayout(boolean, int, int, int, int)View测量后的布局方法,用于设置View的位置
onSizeChanged(int, int, int, int)在View尺寸发生变化的时候调用
onDraw(android.graphics.Canvas)在Canvas上开始绘制View
onKeyDown(int, KeyEvent)物理按键被按下的时候调用
onKeyUp(int, KeyEvent)物理按键抬起的时候调用时候调用
onTrackballEvent(MotionEvent)在View尺寸发生变化的时候调用
onFocusChanged(boolean, int, android.graphics.Rect)该方法在View焦点发生变化的时候被调用
onWindowFocusChanged(boolean)包含当前View的Window获得或失去焦点时被调用
onAttachedToWindow()当前View附加到Window时候调用
onDetachedFromWindow()当前View从Window上分离时候调用
onVisibilityChanged(View, int)当前View或其祖先的可见性改变时被调用
onWindowVisibilityChanged(int)当前View的window可见性改变时被调用
onFinishInflate()当View中所有的子控件均被映射成xml后触发,可用于初始化控件和数据

View与Activity的生命周期

在View的Measure过程中我们能看到下面相关方法,并且从下面周期中能为我们获取View大小的时机带来启发

进入Activity

在这里插入图片描述

点击Home键回到桌面

在这里插入图片描述

重新进入App

在这里插入图片描述

退出Activity

在这里插入图片描述

深度解析View构造函数中的参数defStyleAttr
Android View与Activity生命周期的关系

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值