zoukankan      html  css  js  c++  java
  • Android Developers:拖动和缩放

    这个课程描述了如何使用手势来拖拽和缩放屏幕的对象,使用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()方法被设计为和多点工作。它返回被执行的动作,不包含点的索引位 

     

    // 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, 0); 
           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); 
                
           // Only move if the ScaleGestureDetector isn't processing a gesture. 
           if (!mScaleDetector.isInProgress()) { 
               // 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 == 0 ? 1 : 0; 
               mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);  
               mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);  
               mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex); 
           } 
           break; 
       } 
       }        
       return true; 
    } 
     

    使用触摸来执行缩放 

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

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

     

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

     

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

     

    private ScaleGestureDetector mScaleDetector; 
    private float mScaleFactor = 1.f; 
     
    public MyCustomView(Context mContext){ 
       ... 
       // View code goes here 
       ... 
       mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
    } 
     
    @Override 
    public boolean onTouchEvent(MotionEvent ev) { 
       // Let the ScaleGestureDetector inspect all events. 
       mScaleDetector.onTouchEvent(ev); 
       return true; 
    } 
     
    @Override 
    public void onDraw(Canvas canvas) { 
       super.onDraw(canvas); 
     
       canvas.save(); 
       canvas.scale(mScaleFactor, mScaleFactor); 
       ... 
       // onDraw() code goes here 
       ... 
       canvas.restore(); 
    } 
     
    private class ScaleListener  
           extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
       @Override 
       public boolean onScale(ScaleGestureDetector detector) { 
           mScaleFactor *= detector.getScaleFactor(); 
     
           // Don't let the object get too small or too large. 
           mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f)); 
     
           invalidate(); 
           return true; 
       } 
    } 
  • 相关阅读:
    POJ-1330 Nearest Common Ancestors(倍增的LCA)
    POJ-1442 Black Box(手写堆优化)
    POJ-2442 Sequence(手写堆优化)
    BZOJ2506 calc
    BZOJ3396 [Usaco2009 Jan]Total flow 水流
    BZOJ3570 DZY Loves Physics I
    BZOJ1101 [POI2007]Zap
    BZOJ1110 [POI2007]砝码Odw
    BZOJ1555 KD之死
    BZOJ3476 [Usaco2014 Mar]The Lazy Cow
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3478483.html
Copyright © 2011-2022 走看看