事件机制分发

news/2024/7/7 12:58:10

相关API

1. MotionEvent : 触屏事件

int ACTION_DOWN=0 : 代表down

int ACTION_MOVE=2 ; 代表move

int ACTION_UP=1 : 代表up

getAction() : 得到事件类型值

getX() : 得到事件发生的x轴坐标(相对于当前视图)

getRawX() :得到事件发生的x轴坐标(相对于屏幕左顶点)

getY() : 得到事件发生的y轴坐标(相对于当前视图)

getRawY() :得到事件发生的y轴坐标(相对于屏幕左顶点)

2. Activity

boolean dispatchTouchEvent(MotionEvent event) : 分发事件

boolean onTouchEvent(MotionEvent event) : 处理事件的回调

3. View

boolean dispatchTouchEvent(MotionEvent event) : 分发事件

boolean onTouchEvent(MotionEvent event) : 处理事件的回调方法

void setOnTouchListener(OnTouchListener l) : 设置事件监听器

void setOnClickListener(OnClickListener l) : 设置点击监听

void setOnLongClickListener(OnLongClickListener l) : 设置长按监听

void setOnCreateContextMenuListener
(OnCreateContextMenuListener l) : 用于创建菜单

4. ViewGroup

boolean dispatchTouchEvent(MotionEvent ev) : 分发事件

boolean onInterceptTouchEvent(MotionEvent ev) : 拦截事件的回调方法

触摸事件的分发与处理

事件产生的顺序为: down–>move–>move…—>up

事件对象被系统创建后, 首先会调用对应Activity对象的dispatchTouchEvent()进行分发

down在分发给视图对象的过程中要确定消费者(onTouchEvent()返回true),如果都返回false, 那事件的消费者只能是Activity了

后面的move和up事件, 将事件分发给消费者(可能是视图对象,也可能是Activity)处理, 如果视图不消费, 直接交给Activity处理消费

每个事件都需要有一个消费者

案例图片移动

用到的View相关方法

int getLeft()

得到当前视图左顶点相对父视图的X轴坐标

int getTop()

得到当前视图左顶点相对父视图的Y轴坐标

int getRight()

得到当前视图右下角点相对父视图的X轴坐标

int getBottom()

得到当前视图右下角点相对父视图的Y轴坐标

layout(int left, int top, int right, int bottom) :

动态指定当前视图在父视图中的定位, 参数为相对父视图的坐标

ViewParent getParent() :

得到当前View的父视图对象

布局很简单

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">

<ImageView
    android:id="@+id/image"
    android:layout_width="120dp"
    android:layout_height="120dp"
    android:src="@drawable/logo"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true" />

</RelativeLayout>

移动imageview并设置拖动范围

private ImageView iv_main;
private RelativeLayout parentView;
private int maxRight;
private int maxBottom;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    iv_main = (ImageView) findViewById(R.id.image);
    //获取父布局
    parentView = (RelativeLayout) iv_main.getParent();

    iv_main.setOnTouchListener(this);
}

private int lastX;
private int lastY;

@Override
public boolean onTouch(View v, MotionEvent event) {
    //得到事件的坐标
    int eventX = (int) event.getRawX();
    int eventY = (int) event.getRawY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //第一次记录lastX,lastY
            lastX = eventX;
            lastY = eventY;
            break;
        case MotionEvent.ACTION_MOVE:
            if (maxRight == 0) {
                maxRight = parentView.getRight();
                maxBottom = parentView.getBottom();
            }
            //计算事件的偏移
            int dx = eventX - lastX;
            int dy = eventY - lastY;
            //根据事件偏移量来移动ImageView
            int left = iv_main.getLeft() + dx;
            int right = iv_main.getRight() + dx;
            int top = iv_main.getTop() + dy;
            int bottom = iv_main.getBottom() + dy;
            //限制left
            if (left < 0) {
                right += -left;
                left = 0;
            }
            //限制top
            if (top < 0) {
                bottom += -top;
                top = 0;
            }
            //限制right
            if (right > maxRight) {
                left -= right - maxRight;
                right = maxRight;
            }
            //限制bottom
            if (bottom > maxBottom) {
                top -= bottom - maxBottom;
                bottom = maxBottom;
            }
            iv_main.layout(left, top, right, bottom);
            lastY = eventY;
            lastX = eventX;
            break;
    }
    return true;//事件被消费,由子view处理
}
}

按键的操作

理解

操作的基本类型

down : 手指按下;
up : 手指从按键上离开

按键操作的顺序: downdowndown…—>up

对按键的任何一个操作, 系统都会创建一个KeyEvent对象来对应这个操作

按键的长按监听: down之后一定时间还没有up时会触发长按监听回调

相关API

KeyEvent

int ACTION_DOWN = 0 : 标识down的常量

int ACTION_UP = 1 : 标识up的常量

int getAction() : 得到事件类型

int getKeyCode() : 得到按键的keycode(唯一标识)

startTracking() : 追踪事件, 用于长按监听

Activity

boolean dispatchKeyEvent(KeyEvent event) : 分发事件

boolean onKeyDown(int keyCode, KeyEvent event) : 按下按键的回调

boolean onKeyUp(int keyCode, KeyEvent event) : 松开按键的回调

boolean onKeyLongPress(int keyCode, KeyEvent event) : 长按按键的回调

案例:点击返回键两秒后退出程序

//是否离开
private boolean isExit = false;
Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if (msg.what == 1) {
          isExit=false;
        }
        super.handleMessage(msg);
    }
};

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (!isExit) {//不离开
        isExit = true;
        Toast.makeText(this, "再点击一次退出程序", Toast.LENGTH_SHORT).show();
        handler.sendEmptyMessageDelayed(1, 2000);//两秒后执行
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

http://www.niftyadmin.cn/n/3648994.html

相关文章

Android TabActivity的生命周期

在TabActivity中&#xff0c;只在第一次进入时走了onCreate()、onStart()、onResume()三个阶段&#xff0c;然后在退出该页面时走了onPause()、onStop()和onDestroy()两个阶段。其他时间无论其中的子Activity如何切换&#xff0c;都不会再进入TabActivity的生命周期。 而子Acti…

three.js使用svg_如何使用SVG和anime.js构建弹性范围输入

three.js使用svg介绍 (Introduction) In HTML5, many new types of input attributes were introduced for the form element, such as color, date, range, and many more. Although functionally these new types of input works, they often do not meet the aesthetic need…

我们正处在IT殖民时代,需要突破的勇气,或者就这样继续下去...

IT殖民地&#xff0c;似乎有点危言耸听。但是从客观的事实来看&#xff0c;这个称呼并不离奇&#xff0c;尤其在企业级市场上&#xff08;IT消费品市场还好些&#xff09;。我们的操作系统都是Windows、AIX、HP-UX、Solaris&#xff0c;Redhat Linux&#xff0c;SuSE Linux&…

Android 使用Fragment 替换 TabActivity

可以分为下面的几部分&#xff1a; 使用支持库 创建一个Fragment 创建一个动态UI 多个Fragment之间的通信 1、使用支持库 如果您的应用需要运行在3.0及以上的版本&#xff0c;可以忽略这部分内容。 如果您的应用使用在3.0以下、1.6及以上的版本&#xff0c;需要使用支持库来…

如何在Visual Studio Code中使用Live Share

介绍 (Introduction) Live Share is an extension for VS Code that enables real-time collaboration between developers. It gives users the ability to share a session with someone else, allowing them to edit code as well as share a sever and debugging session. …

四大组件之service简单介绍和AIDL的简单使用

Service是什么 1.Service是一个应用组件, 它用来在后台完成一个时间跨度比较大的工作且没有关联任何界面 2.一个Service可以完成下面这些工作:访问网络 播放音乐 文件IO操作 大数据量的数据库操作 …… 3. 服务的特点: Service在后台运行&#xff0c;不用与用户进行交互 …

[收藏]五种提高 SQL 性能的方法

五种提高 SQL 性能的方法发布日期&#xff1a; 4/1/2004| 更新日期&#xff1a; 4/1/2004Johnny Papa Data Points Archive 有时&#xff0c; 为了让应用程序运行得更快&#xff0c;所做的全部工作就是在这里或那里做一些很小调整。啊&#xff0c;但关键在于确定如何进行调整&a…

Android使用Fragment来实现TabHost的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信

如新浪微博下面的标签切换功能&#xff0c;我以前也写过一篇博文&#xff08;http://www.cnblogs.com/tiantianbyconan/archive/2012/02/24/2366237.html&#xff09;&#xff0c;可以实现&#xff0c;用的是TabHost。但是android发展比较迅速&#xff0c;TabHost这玩意现在已经…