view

View常用的方法(自定义的时候要重写)

onLayout()

用于对子控件进行布局,相当于绝对布局

onMeasure方法

onMeasure会调用两次

view会先调用该方法对视图的大小进行测量
他的参数

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //两个参数都包含两个信息,测量模式和测量值

        int size = MeasureSpec.getSize(widthMeasureSpec);
        int mode = MeasureSpec.getMode(widthMeasureSpec);

}

用于测量控件的大小,接受两个参数
widthMeasureSpec
heightMeasureSpec

  • 测量模式有三种
    1. ECACTLY
    2. AT_OST
    3. UNSPECIFIED

自己设置view 的大小

setMeasuredDimension(mWidth,mHeigth);
生成带有模式的测量参数
MeasureSpec.makeMeasureSpec(mWidth,MeasureSpec.AT_MOST);

onDraw()

在构造函数中创建画笔

mArcPaint =  new  Paint();
mArcPaint.setAntiAlias(true);
mArcPaint.setStyle(Paint.Style.STROKE);
mArcPaint.setStrokeWidth(10);
mArcPaint.setColor(Color.GREEN);

在view使用矩阵进行图形的变换

使用matrix绘制矩阵
三个前缀,四个方法
pre post set
Translate Rotate Scale Skew

View提供的获取坐标方法

  • getTop():获取到的是View自身的顶边到父布局顶边的距离。
  • getLeft():获取到的是View自身的左边到其父布局左边的距离
  • getRight():获取的是View自身的右边到其父布局左边的距离
  • getBottom():获取的是View自身的底边到其父布局顶边的距离

MotionEvent提供的方法

  • getX():获取点击事件距离控件左边的距离,即视图坐标
  • getY():获取点击事件距离控件顶边的距离,即视图坐标
  • getRawX(): 获取点击事件距离整个屏幕左边的距离,即绝对坐标
  • getRawY(): 获取点击事件距离整个屏幕顶边的距离,即绝对坐标

onTouchEvent()

  • 返回true表示处理触控,返回false表示不进行处理
    对单点触控和多点触控进行处理
/*  如果return true,表示onTouchEvent处理完事件后消费了此次事件。此时事件终结;
 *如果return fasle,则表示不响应事件,那么该事件将会不断向上层View的onTouchEvent方法传递
 */
 @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        //多点触摸时使用
        int masked = event.getActionMasked();
        switch (masked) {
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
        }
        //手指落在控件上点的个数
        int pointerCount = event.getPointerCount();
        /**
         * 点的坐标再当前控件的坐标系下,会根据当前view 的缩放比和旋转进行变化。。
         *一般是以当前view 的左上角为0点
         */
         //单点操控手指落在屏幕上的坐标
         float x = event.getX();
         float x1 = event.getX(0);//多点操控时第几个点的坐标
         //获得屏幕上的绝对坐标值
         float rawX = event.getRawX();
         //手指在屏幕上点击的区域
         float size = event.getSize();
         float size1 = event.getSize(0);//多点
         return super.onTouchEvent(event);
    }

事件分发的方法

传递方式:
ViewGroup调用onInterceptTouchEvent方法查看时候是要拦截传递,
1. 如果拦截,然后调用onTouchEvent查看是否消费该事件
1. 如果消费直接在该viewGroup中处理触摸事件。
2. 如果不消费再查看子控件是否能够消费触摸事件。
2. 如果不拦截,直接去子控件查看是否能够消费触摸事件。
1. 如果能够消费,ViewGroup会将触摸事件传递给该控件。
2. 如果不能消费,onTouchEvent返回false。

![事件分发流程](https://img-blog.csdn.net/20160806171230593)

dispatchTouchEvent方法

事件分发的调度,是否将触摸事件向下传递
返回值与onInterceptTouchEvent和onTouchEvent方法的返回值有关

/* * 返回true,表示该View内部消化掉了所有事件。 
   * 返回false,表示View内部只处理了ACTION_DOWN事件,事件继续传递,向上级ViewGroup传递。 
   * 注意View里面是没有onInterceptTouchEvent函数(你已经是最底层劳动人员了,你还能把任务分配给谁) */
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    Log.d(TAG, "dispatchTouchEvent: " + event.getAction());
    return super.dispatchTouchEvent(event);
    }
  • 返回值实例
    onInterceptTouchEvent 返回true,onTouchEvent返回true
    D/CustomViewGroupTestTouchEvent: dispatchTouchEvent: true
    D/CustomViewGroupTestTouchEvent: dispatchTouchEvent: true
    onInterceptTouchEvent 返回true,onTouchEvent返回true
    onInterceptTouchEvent 返回true,onTouchEvent返回true
    onInterceptTouchEvent 返回true,onTouchEvent返回true
    onInterceptTouchEvent 返回true,onTouchEvent返回true
    onInterceptTouchEvent 返回true,onTouchEvent返回true

onInterceptTouchEvent方法

需要自己处理触摸事件的时候返回true,自己不进行事件的吸收让子控件进行处理的话返回false

  • return true :表示将事件进行拦截,并将拦截到的事件交由本层控件 的 onTouchEvent 进行处理;

  • return false :则表示不对事件进行拦截,事件得以成功分发到子View。并由子View的dispatchTouchEvent进行处理。

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
           break;
        }
        return super.dispatchTouchEvent(event);
}

Android Scroll分析

view 的移动

  • 示例:view的移动
@Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getRawX();
        int rawY = (int) event.getRawY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastX = rawX;
                mLastY = rawY;
                break;
            case MotionEvent.ACTION_MOVE:
                int offSerX = rawX - mLastX;
                int offSetY = rawY - mLastY;
                layout( getLeft()+offSerX,
                        getTop()+offSetY,
                        getRight()+offSerX,
                        getBottom()+offSetY);
                mLastX = rawX;
                mLastY = rawY;
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return true;
    }
    //API封装的移动方法,只需要计算出偏移量
    offsetLeftAndRight(offSerX);
    offsetTopAndBottom(offSetY);

view 的弹性滑动

  • scrollTo
  • scrollBy

按照下面的步骤进行

  • 搞懂view的滑动原理
  • 搞懂如何实现弹性滑动
  • 搞懂view的滑动冲突
  • 搞懂view的measure、layout和draw
  • 然后再学习几个已有的自定义view的例子
  • 最后就可以搞定自定义view了,所谓万变不离其宗
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值