三种现实drag方式
  1,在3.0以后可以直接用 View.OnDragListener (在onTouchEvent中调用某个view的startDrag())
  2,onTouchEvent() 
  3,GestureDetector.SimpleOnGestureListener 的onScroll

Dragging

  This lesson describes how to use touch gestures to drag, using onTouchEvent() to intercept touch events.

1.Drag an Object

  If you are targeting Android 3.0 or higher, you can use the built-in drag-and-drop event listeners with View.OnDragListener, as described in Drag and Drop.

A common operation for a touch gesture is to use it to drag an object across the screen. The following snippet lets the user drag an on-screen image. Note the following:

  • In a drag (or scroll) operation, the app has to keep track of the original pointer (finger), even if additional fingers get placed on the screen. For example, imagine that while dragging the image around, the user places a second finger on the touch screen and lifts the first finger. If your app is just tracking individual pointers, it will regard the second pointer as the default and move the image to that location.

    拖拽和滚动手势时,要支持手指交换移动或拖拽,以拖图片为例,当第二个手指按图片且第一个手指离开后,第二个手指应仍然可以拖拽。
  • To prevent this from happening, your app needs to distinguish between the original pointer and any follow-on pointers. To do this, it tracks the ACTION_POINTER_DOWN and ACTION_POINTER_UP events described in Handling Multi-Touch GesturesACTION_POINTER_DOWN and ACTION_POINTER_UP are passed to the onTouchEvent() callback whenever a secondary pointer goes down or up.
    为了实现第一条,应该注意原始手指和后续手指。
  • In the ACTION_POINTER_UP case, the example extracts this index and ensures that the active pointer ID is not referring to a pointer that is no longer touching the screen. If it is, the app selects a different pointer to be active and saves its current X and Y position. Since this saved position is used in the ACTION_MOVE case to calculate the distance to move the onscreen object, the app will always calculate the distance to move using data from the correct pointer.

  The following snippet enables a user to drag an object around on the screen. It records the initial position of the active pointer, calculates the distance the pointer traveled, and moves the object to the new position. It correctly manages the possibility of additional pointers, as described above.

  Notice that the snippet uses the getActionMasked() method. You should always use this method (or better yet, the compatability version MotionEventCompat.getActionMasked()) to retrieve the action of a MotionEvent. Unlike the older getAction() method, getActionMasked() is designed to work with multiple pointers. It returns the masked action being performed, without including the pointer index bits.

getActionMasked() 而不用 getAction(),前者支持多点触摸。
在屏幕上拖拽一个目标的示例
 // The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID; @Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev); final int action = MotionEventCompat.getActionMasked(ev); switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex); // Remember where we started (for dragging)
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer (for dragging)
mActivePointerId = MotionEventCompat.getPointerId(ev, );
break;
} case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex); // Calculate the distance moved
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY; mPosX += dx;
mPosY += dy; invalidate(); // Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y; break;
} case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
} case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
} case MotionEvent.ACTION_POINTER_UP: { final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex); if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == ? : ;
mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
break;
}
}
return true;
}

2.Drag to Pan(拖到托盘上)

  The previous section showed an example of dragging an object around the screen. Another common scenario is panning, which is when a user's dragging motion causes scrolling in both the x and y axes. The above snippet directly intercepted the MotionEvent actions to implement dragging. The snippet in this section takes advantage of the platform's built-in support for common gestures. It overrides onScroll() in GestureDetector.SimpleOnGestureListener.

  To provide a little more context, onScroll() is called when a user is dragging his finger to pan the content. onScroll() is only called when a finger is down; as soon as the finger is lifted from the screen, the gesture either ends, or a fling gesture is started (if the finger was moving with some speed just before it was lifted). For more discussion of scrolling vs. flinging, see Animating a Scroll Gesture.

  Here is the snippet for onScroll():

 // The current viewport. This rectangle represents the currently visible
// chart domain and range.
private RectF mCurrentViewport =
new RectF(AXIS_X_MIN, AXIS_Y_MIN, AXIS_X_MAX, AXIS_Y_MAX); // The current destination rectangle (in pixel coordinates) into which the
// chart data should be drawn.
private Rect mContentRect; private final GestureDetector.SimpleOnGestureListener mGestureListener
= new GestureDetector.SimpleOnGestureListener() {
... @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
// Scrolling uses math based on the viewport (as opposed to math using pixels). // Pixel offset is the offset in screen pixels, while viewport offset is the
// offset within the current viewport.
float viewportOffsetX = distanceX * mCurrentViewport.width()
/ mContentRect.width();
float viewportOffsetY = -distanceY * mCurrentViewport.height()
/ mContentRect.height();
...
// Updates the viewport, refreshes the display.
setViewportBottomLeft(
mCurrentViewport.left + viewportOffsetX,
mCurrentViewport.bottom + viewportOffsetY);
...
return true;
}

  The implementation of onScroll() scrolls the viewport in response to the touch gesture:

 /**
* Sets the current viewport (defined by mCurrentViewport) to the given
* X and Y positions. Note that the Y value represents the topmost pixel position,
* and thus the bottom of the mCurrentViewport rectangle.
*/
private void setViewportBottomLeft(float x, float y) {
/*
* Constrains within the scroll range. The scroll range is simply the viewport
* extremes (AXIS_X_MAX, etc.) minus the viewport size. For example, if the
* extremes were 0 and 10, and the viewport size was 2, the scroll range would
* be 0 to 8.
*/ float curWidth = mCurrentViewport.width();
float curHeight = mCurrentViewport.height();
x = Math.max(AXIS_X_MIN, Math.min(x, AXIS_X_MAX - curWidth));
y = Math.max(AXIS_Y_MIN + curHeight, Math.min(y, AXIS_Y_MAX)); mCurrentViewport.set(x, y - curHeight, x + curWidth, y); // Invalidates the View to update the display.
ViewCompat.postInvalidateOnAnimation(this);
}

手势识别官方教程(6)识别拖拽手势用GestureDetector.SimpleOnGestureListener和onTouchEvent的更多相关文章

  1. 手势识别官方教程(2)识别常见手势用GestureDetector+手势回调接口/手势抽象类

    简介 GestureDetector识别手势. GestureDetector.OnGestureListener是识别手势后的回调接口.GestureDetector.SimpleOnGesture ...

  2. 手势识别官方教程(7)识别缩放手势用ScaleGestureDetector.GestureDetector和ScaleGestureDetector.SimpleOnScaleGestureListener

    Use Touch to Perform Scaling As discussed in Detecting Common Gestures, GestureDetector helps you de ...

  3. 手势识别官方教程(7)识别缩放手势用ScaleGestureDetector和SimpleOnScaleGestureListener

    1.Use Touch to Perform Scaling As discussed in Detecting Common Gestures, GestureDetector helps you ...

  4. 手势识别官方教程(3)识别移动手势(识别速度用VelocityTracker)

    moving手势在onTouchEvent()或onTouch()中就可识别,编程时主要是识别积云的速度用VelocityTracker等, Tracking Movement This lesson ...

  5. 手势识别官方教程(4)在挑划或拖动手势后view的滚动用ScrollView和 HorizontalScrollView,自定义用Scroller或OverScroller

    简单滚动用ScrollView和 HorizontalScrollView就够.自定义view时可能要自定义滚动效果,可以使用 Scroller或 OverScroller Animating a S ...

  6. 手势识别官方教程(8)拦截触摸事件,得到触摸的属性如速度,距离等,控制view展开

    onInterceptTouchEvent可在onTouchEvent()前拦截触摸事件, ViewConfiguration得到触摸的属性如速度,距离等, TouchDelegate控制view展开 ...

  7. Blend4精选案例图解教程(三):一键拖拽

    原文:Blend4精选案例图解教程(三):一键拖拽 拖拽效果,常规实现方法是定义MoveLeftDwon.MoveLeftUp.MouseMove事件,在Blend的世界里,实现对象的拖拽,可以不写一 ...

  8. 关于PC端与手机端随着手指移动图片位置放生变化的拖拽事件

    当按下鼠标时,图片随鼠标移动松开时图片回到原位 drag("div_id") function drag(node_id){ var node = document.getElem ...

  9. android银行卡匹配、详情展开动画、仿爱奇艺视频拖拽、扫码识别手机号等源码

    Android精选源码 android实现银行卡匹配信息源码 android实现可以展开查看详情的卡片 下拉刷新,上拉加载,侧滑显示菜单等效果RefreshSwipeRecyclerview andr ...

随机推荐

  1. [转]select模型的一种技巧运用-libevent

    参见网址 http://www.cppblog.com/xvsdf100/archive/2013/12/10/204689.html

  2. 快速排序算法 Quick sort

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4046189.html 首先随机选择一个轴,并调整数组内各个数字,使得比轴值大的数在轴的右边, ...

  3. centos 7.0 mono&Jexus V5.5.3安装

    首先我们需要先配置一下yum源中mono的引用说明: 第一步: vi /etc/yum.repos.d/mono.repo 第二步:在刚打开的文件中编辑如下内容 [mono]name=monobase ...

  4. LESS语法备忘

    变量 很容易理解: @nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; } 输出: # ...

  5. discuz 重新定义jquery的$

    最近做个小插件 发现加了这个代码不执行: $.ajax({ url:'plugin.php?id=register:regeist_jiangsu', type:'post', data:{ 'mob ...

  6. sql server触发器的例子

    发布:thebaby   来源:脚本学堂     [大 中 小] 本文介绍下,在sql server数据库中使用触发器的简单例子,有需要的朋友可以参考下,希望对你有一定的帮助. 原文地址:http:/ ...

  7. Css3 阴影效果

    box-shadow:#333 0 0 5px 10px; //上下左右有阴影-webkit-box-shadow: #666 0px 5px 10px; -moz-box-shadow: #666 ...

  8. x86与x64与x86_64

    x86是指intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集,ntel官方文档里面称为“IA ...

  9. 根据版本的不同整理所有的绿色SQL Server

    在这篇论坛文章中,读者可以了解到如何根据不同的SQL Server版本,整理出所有版本的绿色SQL Server的具体方法,详细内容请参考下文: 1. Sqlservr.exe 运行参数 Sql Se ...

  10. Boost format

    浅尝boost之format 概述      std::string是个很不错的东东,但实际使用时基本在每个程序里都会遇到不愉快的事情:格式化字符串.我甚至由于这个原因在代码里引入平台有关的MFC,A ...