安卓手势学习

Touch操作


      touch事件
         touch事件:用户的手势操作
android设备中的应用程序主要依赖于用户的各种手势操作实现交互,
   常见的手势操作有:单击,长按,滑动等;
     onTouchEvent()方法
            在View类中定义了onTouchEvent()方法,用于处理Touch事件,View
的每个子类都可以重写该方法,以决定该View如何处理Touch事件,方法签名为:
    public boolean onTouchEvent(MotionEvent event)
   在Activity类中也定义了onTouchEvent()方法,则每个Activity的子孙类
都可以重写该方法,用于决定当前Activity中如何处理Touch事件,该方法签名与View类定义的
onTouchEvent()方法的签名完全相同。
View.OnTouchListener接口
   在View类中定义了setOnTouchListener()方法,用于为View对象指定Touch事件处理监听器,该方法的参数类型是
View.OnTouchListener接口,借口中的抽象方法签名为:
      boolean onTouch(View v,MotionEvent event);
MotionEvent类
   无论View类或Activity类中定义的onTouchEvent()方法,或View类中的OnTouchListener
接口的抽象方法中,都使用了MotionEvent的对象作为参数,该类的常用方法有:


        public final int getAction()
public final float getX()
public final float getX(int pointerIndex)
public final float getY()
public final float getY(int pointerIndex)


           MotionEvent类中定义了一系列的常量,用于标识Touch操作的类型,亦可用于常识匹配
  getAction()方法的返回值,常用的常量有:
    public static final int ACTION_DOWN
    public static final int ACTION_UP
    public static final int ACTION_MOVE




 处理Touch事件方法的返回值
    无论View类或Activity类中定义的onTouchEvent()方法,或View类中的OnTouchListener接口的抽象方法,
    各方法的返回值均是boolean类型。
  
  由于同一次的某个操作可能导致多个处理Touch事件的方法被回调,当方法的返回值被指定为true时,表示当前
  方法已"消费"该事件,则后续尝试处理该Touch事件的方法不会再被回调,如果返回值被指定为false时,
  则后续尝试处理该Touch事件的方法会正常执行。
 
 处理Touch的三种方法
     View.onTouchEvent()
     Activity.onTouchEvent()
     View.setOnTouchListener()




  简单的自定义View
     当需要自定义View时,需要创建新的java类,继承自View或者View的子孙类。


     由于View没有无参数的构造方法,则自定义View需要显式的创建带参数的构造方法:
              如果希望在程序中使用new关键字创建自定义View的对象,则必须显式的创建
   带1个参数的构造方法;
                       如果希望在res\layout\下的布局文件中使用自定义View设计布局,则必须
   显式的创建带2个参数或者带3个参数的构造方法。




Touch事件的派发和处理逻辑
  事件处理的矛盾
     在ANDROID系统中,视图大致分为View与ViewGroup:
       View是一般独立显示了具体内容的控件,例如TextView、ImageView等。
ViewGroup是用于承载其他控件的,例如RelativeLayout、ListView等。
    当出现Touch事件时,需要明确是由View或是ViewGroup处理事件。




事件处理的相关方法
     在android系统中,视图系统中存在3个方法处理Touch事件相关的逻辑:
         public boolean dispatchTouchEvent(MotionEvent ev):处理事件分发;
 public boolean onInterceptTouchEvent(MotionEvent ev):处理事件拦截;
 public boolean onTouchEvent(MotionEvent ev): 处理事件响应。


    由于简单的View对象不存在子级控件,所以并不存在事件拦截的操作,
       即没有onInterceptTouchEvent()方法。
事件分发与处理
      每个ViewGroup在接收倒事件后,默认遵循“分发->拦截->处理”的流程执行相关的方法。


      在默认情况下:
         事件分发:“隧道式”,即从最外层控件依次传递,直至最内层子级控件,也就是说,越靠近根节点,分发的权力越大。
 事件处理:“冒泡式”,即从最内层子级控件开始处理,直至最外层的控件。

事件分发详解;
  事件分发(dispatchTouchEvent)的逻辑如下:
  当返回值为true时,由dispatchTouchEvent()直接消费,事件将不再传递,
  即不会拦截、响应,更不会向后分发到其它控件;
  当返回值为false时:
        如果事件是Activity获取的,则由Activity的onTouchEvent()消费;
如果事件是父控件的,则由父控件的onTouchEvent()消费。
       事件拦截详解
    时间拦截(onInterceptTouchEvent)的逻辑如下:
      当返回值为true时,表示当前控件拦截事件,且当前控件的onTouchEvent()
      会被执行,事件并不会向后传递到其它的控件。


      当返回值为false时,表示不拦截,即放行,事件将交给子级控件去分发
      (即子级控件的dispatchTouchEvent()方法将被执行)。


事件响应详解
        事件响应(onTouchEvent)的逻辑如下:
当返回值为true时,表示当前控件已消费事件,则整个事件处理过程结束;
当返回值为false时,表示当前控件未消费事件(可能开发人员已便携程序响应,但只要
   返回值为false,就不表示消费了该事件),将由父级控件继续响应,即父级控件的onTouchEvent()
   方法会被调用。


 特殊的单击事件
       在android系统中,关于屏幕上的操作都属于Touch操作,例如单击则是由“按下->弹起”这两种动作组合完成的。


单击事件是直接消费事件,因此,当点击界面上的Button时,一定是由Button处理事件,企鹅其父级控件无法对单击事件进行相应。

手势实现的图库部分代码


package com.edu.cn.image;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AnimationUtils;
import android.widget.ImageSwitcher;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.ViewSwitcher;
import android.widget.ViewSwitcher.ViewFactory;

public class DisplayActivity extends Activity implements ViewFactory {
    private ArrayList<Integer> data;
    private int position;
    private ImageSwitcher imageswitcher;
    ViewSwitcher v;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
  		setContentView(R.layout.activity_display);
	    Intent intent = getIntent();
	    data = intent.getIntegerArrayListExtra("data");
	    position = intent.getIntExtra("position", 0);
	    
	   
	    imageswitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher2);
	   imageswitcher.setFactory(this);
	   
	}
	
	
	private float actionDownX;
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			actionDownX = event.getX();
			break;
        case MotionEvent.ACTION_UP:
			if(event.getX() - actionDownX > 20){
				doShowPrevious();
			}
            if(actionDownX - event.getX() > 20){
            	doShowNext();
			}
			break;
		}
		return super.onTouchEvent(event);
	}
	
	private void doShowPrevious(){
		position--;
		if(position < 0){
			position = data.size() - 1;
		}
		imageswitcher.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.left_to_right));
		imageswitcher.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.left_out_right));
		imageswitcher.setImageResource(data.get(position));
	}
	private void doShowNext(){
		position++;
		if(position >= data.size()){
			position = 0; 
		}
		imageswitcher.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.right_to_left));
		imageswitcher.setInAnimation(AnimationUtils.loadAnimation(this, R.anim.right_out_left));
		imageswitcher.setImageResource(data.get(position));
	}

	@Override
	public View makeView() {
		// TODO Auto-generated method stub
		ImageView view = new ImageView(this);
		view.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
		view.setScaleType(ScaleType.FIT_CENTER);
		view.setImageResource(data.get(position));
		return view;
	}
}


    
posted @   wojiaohuangyu  阅读(7)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示