Android中View的知识体系——(1)初识View

Android中View的知识体系——(1)初识View


作者:黑衣侠客

一、前言

最近在学习MVP的相关知识,但是发现似乎许多东西都是从View开始的,所以今天总结一下View所学的相关知识,在总结中学习,在学习中总结。

二、知识点纲要

1.View和ViewGroup

1.1 View

View是所有控件的基类,下到各种Button、TextView、ImageView,上到LinearLayout、RelateLayout,甚至包括自定义的控件,都是继承View这个基类,所以说,View是代表着界面层的一个抽象控件。

1.2 ViewGroup

Android中的所有UI组件都继承了View类,而View类有一个很重要的子类——ViewGroup,但是ViewGroup通常作为其他组件的容器使用。Android中的所有的UI组件都是建立在View、ViewGroup基础之上的,同时,由于View和ViewGroup的组合器模式,ViewGroup也可以被当做View使用。在Android里,ViewGroup作为容器不仅可以盛装其他普通的View组件,还可以盛装ViewGroup组件,以此类推,ViewGroup再盛装它该装的组件。

2.MotionEvent和TouchSlop函数方法

2.1 MotionEvent

当手指触摸屏幕时(View或ViewGroup派生的控件),将产生Touch事件。Touch事件的相关细节(触摸发生的位置、事件及怎么触摸的)被封装成MotionEvent对象。
事件类型具体动作
MotionEvent.ACTION_DOWN手指刚接触到屏幕
MotionEvent.ACTION_UP手指从屏幕刚松开的一瞬间
MotionEvent.ACTION_MOVE手指在屏幕上移动
MotionEvent.ACTION_CANCEL动作取消(非人为)
正常情况下,一次手指触摸屏幕的行为会触发一系列点击事件,通常分两种:
  • 点击屏幕:事件为DOWN -> UP
  • 点击屏幕滑动后在松开: 事件为DOWN -> MOVE -> MOVE ->…-> MOVE -> UP
在上述的两种典型的Touch事件中,我们可以通过MotionEvent对象得到点击事件发生的x和y坐标。为此,系统提供了两组方法:
  • getX/getY : 返回的是相对于当前View左上角的x和y的坐标
  • getRawX/getRawY : 返回的是相对于手机屏幕左上角的x和y坐标

2.2TouchSlop

TouchSlop是系统所能识别的被认为是滑动的最小距离,即当手指在屏幕上滑动时,如果两次滑动之间的距离小于这个距离常量,那么系统就认为你没有再进行滑动操作,而这个常量与设备有关,在不同的设备这个值是不同的,因此,可通过==ViewConfiguration.get(getContext()).getScaledTouchSlop()==来获取这个常量。该方法可以做到有更好的用户体验。

3.手势(Gesture)

所谓手势,就是用户手指在触摸屏上的连续碰撞行为,例如:在屏幕上画出从左至右的动作,在比如:在屏幕上画出一个圆圈也是手势。手势这种连续的碰撞会形成某个方向上的移动趋势,也会形成一个不规则的几何图形。Android对这两种手势都提供了支持。

第一种手势行为:Android提供了手势检测,并为手势检测提供了相应的监听器
第二种手势行为:Android允许开发者添加手势,并提供相应的API识别用户的手势

下面是一些重要的类:

3.1 VelocityTracker

速度追踪,用于追踪手指划动过程中的速度,可以是水平也可以是垂直方向的速度。
首先,在View的onTouchEvent方法中追踪当前点击事件的速度。
		VelocityTracker tracker = VelocityTracker.obtain();
		tracker.addMovement(event);
接着,当我们想知道当前的滑动速度时,这个时候可以采用以下方式获取当前的速度。
	tracker.computeCurrentVelocity(1000);//时间间隔的单位是:毫秒(ms)
	//意思是1s时间内运动了多少个像素
	float  xVelocity = tracker.getXVelocity();
	float  yVelocity = tracker.getYVelocity();

注意

  • 在通过getXVelocity和getYVelocity获取速度之前应先调用computeCurrentVelocity()方法初始化时间。
  • 这里的速度指的是一段时间内手指所滑过的像素。
  • 例如:时间间隔设置为1000ms时,在1s内,手指在水平方向上从左至右滑动100像素,那么水平速度就是100,同样需要注意的是,速度可以是负值,当手指从右至左滑动时,水平方向值为负值,速度计算公式如下:

速度 = (终点位置 — 起点位置)/ 时间段

3.2 GestureDetector

Android为手势提供了一个GestureDetector类,GestureDetector实例代表了一个手势检测器,用于辅助检测用户的单击、滑动、长按、双击等行为。GestureDetector有3个Listener接口,用来回调不同的触摸事件,具体如下:
GestureDetector这个类对外提供了3个接口和一个静态内部类下面简单的介绍一下这4个监听器:
监听器简介
OnGestureListener手势检测,主要有:按下(Down)、快速滑动(Fling)、长按(LongPress)、滚动(Scroll)、触摸反馈(ShowPress)和单击抬起(SingleTapUp)
OnDoubleTapListener双击检测,主要有三个回调类型:双击(DoubleTap)、单击确认(SingleTapConfirmed)和双击事件回调(DoubleTapEvent)
OnContextClickListener这是Android6.0(23)才添加的,用于检测外部设备上按钮是否按下,一般情况下可以忽略
SimpleOnGestureListener该类是GestureDetector提供给我们的一个更方便非响应不同手势的类,这个类实现了上述三个接口(但是所有方法都是空的),该类是static类,也就是说它是一个外部类。可以在外部继承这个类,重写里面的手势处理方法。
		public static class SimpleOnGestureListener implements OnGestureListener , OnDoubleTapListener , OnContextClickListener	

另外通过GestureDetector的构造方法可以将SimpleOnGestureListener对象传递进去,这样GestureDetector能处理不同的手势了。

构造函数
GestureDetector有5种构造函数,在这里我们讨论两个主要的构造函数:
//第一种构造函数
public GestureDetector (Context context , OnGestureListener listener){
		this(context,listener,null);
}	
在第一种构造函数中,需要传入两个参数,context(上下文)和OnGestureListener(手势监听器),我们经常用的就是这种方式。
//第二种构造函数
	public GestureDetector(Context context , OnGestureListener listener , Handler handler){
       if(handler!=null){
           mHandler = new GestureHandler(handler);
       }else{
           mHandler = new Gesturehandler();
       }
       mListener = listener;
       if(listener instanceof OnDoubleTapListener){
           setOnDoubleTapListener((OnDoubleTapListener) listener);
       }
       if(listener instanceof OnContextClickListener){
           setContextClickListener((OnContextClickListener) listener);
       }
       init(context);
   }
(第二种构造函数)在通常情况下是不需要Handler的,因为它会在内部自动创建一个Handler用于处理数据,如果在主线程中创建GestureDetector,那么它所创建的Handler会自动获取主线程的Looper,如果在没有创建Looper的子线程中创建GestureDetector,那么就会因为无法获取Looper导致创建GestureDetector失败,那么,此时,我们应该传递一个带有Looper的Handler。==
重要方法介绍
方法名描述所属接口
onDown手指触摸屏幕的一瞬间,由一个ACTION_DOWN触发OnGestureListener
onShowPress手指触摸屏幕,尚未松开或拖动,由一个ACTION_DOWN触发,注意:它强调的是没有松开或拖动的状态OnGestureListener
onSingleTapUp手指触摸屏幕后松开,伴随着1个ACTION_UP而触发这是单击行为OnGestureListener
onScroll手指按下屏幕并拖动,由一个ACTION_DOWN和多个ACTION_MOVE触发,这是拖动行为
onLongPress用户长按着屏幕不放,即长按OnGestureListener
onFling用户按下触摸屏、快速滑动后松开,由1个ACTION_DOWN和多个ACTION_MOVE以及1个ACTION_UP触发,这是快速滑动行为OnGestureListener
onDoubleTap双击、有两次连续的单击组成,它不可能和onSingleTapConfirmed共存OnDoubleTapListener
onSingleTapConfirmed严格的单击行为。注意:它和onSingleTapUp的区别,如果触发了onSingleTapConfirmed,那么后面不可能在紧跟着另一个单击行为,即这次可能是单击,而不可能是双击中的一次单击OnDoubleTapListener
onDoubleTapEvent表示发生了双击行为,在双击的期间,ACTION_DOWN、ACTION_MOVE和ACTION_UP都会触发此回调OnDoubleTapListener

3.3 Scroller

Scroller是有过渡效果的滑动,它的过程不是瞬间完成的,而是在一定的时间间隔内完成的。Scroller本身无法让View弹性滑动,它需要和View的computeScroll方法配合使用才能完成这个功能。

使用方法:

Scroller scroller = new Scroller(mContext);
//缓慢滚动到指定的位置
private void smoothScrollTo(int destX,int destY){
	int scrollX = getScrollX();
	int delta = destX - scrollX;
	//1000ms内滑向destX,效果就是慢慢滑动
	mScroller.startScroll(scrollX,0,delta,0,1000);
	invalidate();
}
@Override
public void computeScroll(){		//需要与Scroll()配合使用
	if(mScroller.computeScrollOffset()){
		scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
		postInvalidate();
	}
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值