手势和触摸事件

来源:互联网 发布:影视制作需要哪些软件 编辑:程序博客网 时间:2024/04/29 13:01

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

使用

处理点击

所有手势的核心是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文件

<uk.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 bitmapmImageView.setImageDrawable(someBitmap);// Setup view attacherPhotoViewAttacher 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 targetviewDropZone.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  }}
0 0