手势和触摸事件

手势识别和处理触摸事件是开发用户交互的重要事项,处理标准事件例如点击,长按,按键等等是基础的其他教程介绍的,这项教程是关注于处理一些专业的手势例如:
- 向某个方向滑动
- 双击放大
- 手捏放大或缩小
- 滑动列表的效果

使用

处理点击

所有手势的核心是onTouchListeneronTouch 方法后者有对动作数据MotionEvent有访问权限.每个view都有onTouchListener 可以指定:

myView.setOnTouchListener(new OnTouchListener()) {
    @Overdide
    public boolean onTouch(View v, MotionEvent event) {
        //解读动作数据,处理相关事件
    }
});

每个onTouch 都对动作事件具有访问权限,动作事件包含了一个动作代码和一组轴值。动作代码描述了发生的状态的改变,例如指针的上下移动。轴值形容了位置和一些其他的属性:
- getAction 返回一个整数常量MotionEvent.ACTION_DOWN , MotionEvent.ACTION_MOVE, MotionEvent.ACTION_UP
-getX() 返回触摸事件的x坐标
- getY() 返回点击事件的y坐标
记住每个触摸事件可以在整个受影响的view层传播,每个包含这个view的布局都可能会对事件进行反馈。

处理多种触摸事件

记住getAction 正常的包含的信息既包括动作也包括指针索引。在单触摸事件中,只有一个指针(设置为0)不需要位图掩码,在多点触摸情况下需要其他的方法确定触摸事件:
- getActionMasked() 没有指针索引的情况下获取动作事件
- getActionIndex() 获取使用的指针索引
与其他指针相联系的事件一般以MotionEvent.ACTION_POINTER 开始,例如MotionEvent.ACTION_POINTER_DOWNMotionEvent.ACTION_POINTER_UP 使用getPointerCount() 可以知道在触摸序列中多少指针被激活了。

手势探测器

onTouch 事件中我们可以使用GestureDetector 来理解基于一系列动作的手势。

双击

使用OnDoubleTapListener,:

myView.setOnTouchListener(new OnDoubleTapListener(this)) {
    @Override
    public void onDoubleTap(MotionEvent e) {
        Toast.makeText。。。
    }
});

滑动手势探测器

使用onSwipeTouchListener

myView.setOnTouchListener(new OnSwipeTouchListener(this){
    @Override
     public void onSwipeDown() {
    Toast.makeText(MainActivity.this, "Down", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onSwipeLeft() {
    Toast.makeText(MainActivity.this, "Left", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onSwipeUp() {
    Toast.makeText(MainActivity.this, "Up", Toast.LENGTH_SHORT).show();
  }

  @Override
  public void onSwipeRight() {
    Toast.makeText(MainActivity.this, "Right", Toast.LENGTH_SHORT).show();
  }

});

ListView滑动探测

我们可以让ListView的每一项来感应滑动手势,采用第三方库android-swipelistview。待续。。。

缩放

我们可以使用ScaleGestureDetector类

public class ScaleableTextView extends TextView 
        implements OnTouchListener, OnScaleGestureListener {

  ScaleGestureDetector mScaleDetector = 
      new ScaleGestureDetector(getContext(), this);

  public ScaleableTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public boolean onScale(ScaleGestureDetector detector) {
    // Code for scale here
    return true;
  }

  @Override
  public boolean onScaleBegin(ScaleGestureDetector detector) {
    // Code for scale begin here
    return true;
  }

  @Override
  public void onScaleEnd(ScaleGestureDetector detector) {
    // Code for scale end here
  }

  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if (mScaleDetector.onTouchEvent(event))
      return true;
    return super.onTouchEvent(event);
  }
}

缩放图片

最常见的是对ImageView进行缩放操作,需要使用PhotoView
第三方库
XML文件

.co.senab.photoview.PhotoView
    android:id="@+id/iv_photo"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

java:

// Any implementation of ImageView can be used!
mImageView = (ImageView) findViewById(R.id.iv_photo);
// Set the image bitmap
mImageView.setImageDrawable(someBitmap);
// Setup view attacher
PhotoViewAttacher mAttacher = new PhotoViewAttacher(mImageView

滑动列表

对于RecyclerView我们可以使用addOnScrollListener对于ListView我们可以使用setOnScollListener

拖放

首先我们要可拖动的view上添加一个onTouch 处理器,开始拖动的时候可以创建一个DragShadow,我们需要DragShadowBuilder 当拖动开始时

draggableView.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN ) {
            //构建拖动阴影
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            //开始阴影拖动
            view.startDrag(null, shadowBuilder, view, 0);
            //隐藏view
            view.setVisibility(View.INVISIBLE);
            return true;
        }
    } else {
        return false;
    }
}) 

想要添加拖放事件的话我们需要创造一个DragListener 连接到一个拖动的区域。

// This listener is attached to the view that should be a drop target
viewDropZone.setOnDragListener(new OnDragListener() {
  // Drawable for when the draggable enters the drop target
  Drawable enteredZoneBackground = getResources().getDrawable(R.drawable.shape_border_green);
  // Drawable for the default background of the drop target
  Drawable defaultBackground = getResources().getDrawable(R.drawable.shape_border_red);

  @Override
  public boolean onDrag(View v, DragEvent event) {
      // Get the dragged view being dropped over a target view
      final View draggedView = (View) event.getLocalState();
      switch (event.getAction()) {
      case DragEvent.ACTION_DRAG_STARTED:
          // Signals the start of a drag and drop operation.
          // Code for that event here
          break;
      case DragEvent.ACTION_DRAG_ENTERED:
          // Signals to a View that the drag point has 
          // entered the bounding box of the View. 
          v.setBackground(enteredZoneBackground);
          break;
      case DragEvent.ACTION_DRAG_EXITED:
          // Signals that the user has moved the drag shadow 
          // outside the bounding box of the View. 
          v.setBackground(defaultBackground);
          break;
      case DragEvent.ACTION_DROP:
          // Signals to a View that the user has released the drag shadow, 
          // and the drag point is within the bounding box of the View. 
          // Get View dragged item is being dropped on
          View dropTarget = v;
          // Make desired changes to the drop target below
          dropTarget.setTag("dropped");
          // Get owner of the dragged view and remove the view (if needed)
          ViewGroup owner = (ViewGroup) draggedView.getParent();
          owner.removeView(draggedView);
          break;
      case DragEvent.ACTION_DRAG_ENDED:
          // Signals to a View that the drag and drop operation has concluded.
          // If event result is set, this means the dragged view was dropped in target
          if (event.getResult()) { // drop succeeded
              v.setBackground(enteredZoneBackground);
          } else { // drop did not occur
              // restore the view as visible
              draggedView.post(new Runnable() {
                  @Override
                  public void run() {
                      draggedView.setVisibility(View.VISIBLE);
                  }
              });
              // restore drop zone default background
              v.setBackground(defaultBackground);
          }
      default:
          break;
      }
      return true;
  }
});

晃动探测

首先我们需要一个shakeListenerhttps://gist.github.com/nesquena/5d1922a5a50fcfb4436a
然后使用方法:

public class MainActivity extends Activity 
    implements ShakeListener.Callback {

  @Override
  public void shakingStarted() {
    // Code on started here
  }

  @Override
  public void shakingStopped() {
    // Code on stopped here
  }
}

你可能感兴趣的:(android学习)