这个课程描述了如何使用手势来拖拽和缩放屏幕的对象,使用onTouchEvent()方法来获取触摸事件。这里是这节课程使用的源代码。

拖动一个对象

————————————————————————————————————————————————————————————————

如果你把Android3.0或者更高做为目标,你能使用内嵌的,拖和拽事件监听器View.OnDragListener,在Drag and Drop中被描述。

一个触摸手势的常见操作是用它来在屏幕中拖一个对象。下面的代码片段让用户拖动一个屏幕中的图片。记录如下:

  • 在一个拖(或者滑动)操作,应用程序保持跟踪这个最初的点(手指),即使额外的手指被放置的屏幕上。例如,想象当拖动图片转动的时候,用户在这个触摸屏中放置了第二个手指,并且离开了第一个手指。如果应用程序仅仅是跟踪个别的点,它会把第二点作为默认的和移动图片的位置。

  • 为了阻止这个情况的发生,你的应用需要区分最初的点和任何后续的点。为此,它跟踪在Handing Multi-Touch Gestures中被描述的ACTION_POINTER_DOWN和ACTION_POINTER_UP事件。ACTION_POINTER_DOWN和ACTION_POINTER_UP被传递给onTouchEvent()回调方法,当第二个点按下和抬起的时候。

  • 在ACTION_POINTER_UP情况,这个例子提取了索引并确保活动的点的ID没有引用一个不再触摸屏幕的点。如果是这样,应用程序选择一个不同的点活动,并保存它当前的X和Y位置。以为这杯保存的位置被用在ACTION_MOVE情况,来计算在屏幕中的对象移动的距离,应用将总是使用从正确的点的数据来计算移动的距离。

下面的代码块是一个用户在屏幕周围拖拽一个对象。它记录了这个活动点的初始位置,计算这个点移动的距离,并移动这个对象到新的位置。它正确的管理了额外可能的点,如上面所描述。

注意这个代码块使用getActionMasked()方法。你应该总是使用这个方法(或者更好,兼容性版MotionEventCompat.getActionMasked()方法)来获取一个活动的MotionEvent。不像老的getAction()方法,getActionMasked()方法被设计为和多点工作。它返回被执行的动作,不包含点的索引位。

  1. // The ‘active pointer’ is the one currently moving our object.
  2. private int mActivePointerId = INVALID_POINTER_ID;
  3.  
  4. @Override
  5. public boolean onTouchEvent(MotionEvent ev) {
  6. // Let the ScaleGestureDetector inspect all events.
  7. mScaleDetector.onTouchEvent(ev);
  8.  
  9. final int action = MotionEventCompat.getActionMasked(ev);
  10.  
  11. switch (action) {
  12. case MotionEvent.ACTION_DOWN: {
  13. final int pointerIndex = MotionEventCompat.getActionIndex(ev);
  14. final float x = MotionEventCompat.getX(ev, pointerIndex);
  15. final float y = MotionEventCompat.getY(ev, pointerIndex);
  16.  
  17. // Remember where we started (for dragging)
  18. mLastTouchX = x;
  19. mLastTouchY = y;
  20. // Save the ID of this pointer (for dragging)
  21. mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
  22. break;
  23. }
  24.  
  25. case MotionEvent.ACTION_MOVE: {
  26. // Find the index of the active pointer and fetch its position
  27. final int pointerIndex =
  28. MotionEventCompat.findPointerIndex(ev, mActivePointerId);
  29.  
  30. final float x = MotionEventCompat.getX(ev, pointerIndex);
  31. final float y = MotionEventCompat.getY(ev, pointerIndex);
  32.  
  33. // Only move if the ScaleGestureDetector isn't processing a gesture.
  34. if (!mScaleDetector.isInProgress()) {
  35. // Calculate the distance moved
  36. final float dx = x - mLastTouchX;
  37. final float dy = y - mLastTouchY;
  38.  
  39. mPosX += dx;
  40. mPosY += dy;
  41.  
  42. invalidate();
  43. }
  44. // Remember this touch position for the next move event
  45. mLastTouchX = x;
  46. mLastTouchY = y;
  47.  
  48. break;
  49. }
  50.  
  51. case MotionEvent.ACTION_UP: {
  52. mActivePointerId = INVALID_POINTER_ID;
  53. break;
  54. }
  55.  
  56. case MotionEvent.ACTION_CANCEL: {
  57. mActivePointerId = INVALID_POINTER_ID;
  58. break;
  59. }
  60.  
  61. case MotionEvent.ACTION_POINTER_UP: {
  62.  
  63. final int pointerIndex = MotionEventCompat.getActionIndex(ev);
  64. final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
  65.  
  66. if (pointerId == mActivePointerId) {
  67. // This was our active pointer going up. Choose a new
  68. // active pointer and adjust accordingly.
  69. final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
  70. mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
  71. mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
  72. mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
  73. }
  74. break;
  75. }
  76. }
  77. return true;
  78. }

使用触摸来执行缩放

————————————————————————————————————————————————————————————————

如在Detecting Common Gestures中被讨论的,GestureDetector帮助你检查Android常用的手势,如滑动,finging,和长按。对于滑动,Android提供了ScaleGestureDetector。GestureDetector和ScaleGestureDetector能一起使用,当你想一个View认识一个额外的手势的时候。

为了报告检测到的手势事件,手势检测器使用监听对象被传递给它们的构造方法。ScaleGestureDetector使用ScaleGestureDetector.OnScaletureListener。Android提供ScaleGestureDetector.SimpleOnScaleGestureListener作为一个帮助类,如果你不关心所有的被报告的时间,你能继承。

这里是一个代码片段,它给了你如何执行缩放的基本想法。这里的源代码:

  1. private ScaleGestureDetector mScaleDetector;
  2. private float mScaleFactor = 1.f;
  3.  
  4. public MyCustomView(Context mContext){
  5. ...
  6. // View code goes here
  7. ...
  8. mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
  9. }
  10.  
  11. @Override
  12. public boolean onTouchEvent(MotionEvent ev) {
  13. // Let the ScaleGestureDetector inspect all events.
  14. mScaleDetector.onTouchEvent(ev);
  15. return true;
  16. }
  17.  
  18. @Override
  19. public void onDraw(Canvas canvas) {
  20. super.onDraw(canvas);
  21.  
  22. canvas.save();
  23. canvas.scale(mScaleFactor, mScaleFactor);
  24. ...
  25. // onDraw() code goes here
  26. ...
  27. canvas.restore();
  28. }
  29.  
  30. private class ScaleListener
  31. extends ScaleGestureDetector.SimpleOnScaleGestureListener {
  32. @Override
  33. public boolean onScale(ScaleGestureDetector detector) {
  34. mScaleFactor *= detector.getScaleFactor();
  35.  
  36. // Don't let the object get too small or too large.
  37. mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
  38.  
  39. invalidate();
  40. return true;
  41. }
  42. }

Android Developers:拖动和缩放的更多相关文章

  1. Android拖动和缩放图片

    Android拖动和缩放图片 2014年5月9日 我们在使用应用其中常常须要浏览图片.比方在微信其中.点击图片之后能够对图片进行缩放. 本博客介绍怎样对图片进行拖拽和缩放.这首先要了解Android中 ...

  2. 【Android Developers Training】 72. 缩放一个视图

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  3. Android拖动和缩放

    拖拽和缩放 多点触控的理论学完了之后,这里开始实践.本节主要介绍使用onTouchEvent()方法处理触控事件. 拖动一个对象 如果你使用的是Android 3.0或者之后的系统,那么你可以使用内置 ...

  4. 【Android Developers Training】 68. 序言:添加动画

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  5. 【Android Developers Training】 67. 响应触摸事件

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  6. 【Android Developers Training】 60. 在你的UI中显示位图

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. 【Android Developers Training】 52. 打印照片

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  8. 【Android Developers Training】 48. 轻松拍摄照片

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. 【Android Developers Training】 9. 覆盖于布局之上的Action Bar

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

随机推荐

  1. treeview 点击时选中节点

    private void tv_WebList_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { Point clickPo ...

  2. JavaWeb学习总结(三十五)——使用JDBC处理Oracle大数据

    一.Oracle中大数据处理 在Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了.因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种 ...

  3. 如何使用GetManifestResourceStream

    在做开发时想要从程序集中加载一个xml文件数据,可是在运行后确取不到值,值始终是null. 代码如下: Stream ss = this.GetType().Assembly.GetManifestR ...

  4. 【HDOJ】2828 Lamp

    DLX简单题目. /* */ #include <iostream> #include <sstream> #include <string> #include & ...

  5. Tolerance (定义发票允差)

    (N) AP > Setup > Invoice > Tolerance (定义发票允差) 这里只对价格进行了设置,其他保持了默认.To set tolerance levels f ...

  6. c#基础这些你都看过吗?(一)-----仅供初学者使用

    1.注释(不写注释是流氓,名字瞎起是扯淡)‘///’一般用于注释函数,注释类.2.快捷键ctrl+k+d(有语法错误无法进行对齐)ctrl+j(快速弹出只能提示)shift+end,shift+hom ...

  7. Asp.net性能优化技巧

    [摘 要] 我只是提供我几个我认为有助于提高写高性能的asp.net应用程序的技巧,本文提到的提高asp.net性能的技巧只是一个起步,更多的信息请参考<Improving ASP.NET Pe ...

  8. 【 D3.js 选择集与数据详解 — 1 】 使用datum()绑定数据

    选择集和数据的关系是 D3 最重要的基础,在[入门 - 第 7 章]时进行过些许讲解,对于要掌握好 D3 是远远不够的.故此开设一个新的分类,专门讨论选择集与数据的关系,包括数据绑定的使用和工作原理, ...

  9. ACM ICPC Asia Regional 2011 Kuala Lumpur C题

    看了逆波兰表达式之后,发现真是强悍的数据结构,栈的应用怎么感觉一辈子也学不完了呢 后缀表达式即逆波兰表达式,就是将所有的运算符按照一定的等级全部都安排到数字的后面去,实现正确的运算法则. OK,代码要 ...

  10. 【转】objective-c基本数据类型之输出格式符

    原文网址:http://blog.csdn.net/mamong/article/details/8255691 基本数据类型 1. int 输出格式符:%i, %d, %o %x, 2. float ...