Android事件机制——-MotionEvent

本文详细探讨了Android中的MotionEvent事件机制,包括事件类型、发生顺序及API用法,重点讲解了MotionEvent如何用于触屏事件处理。同时,通过一个基础的拖动图片案例,展示了在MotionEventActivity中如何利用RelativeLayout和ImageView实现事件分发和处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android事件机制——-MotionEvent

1、提出问题?

1)Android是如何响应对其中的某个视图的操控操作呢?   

    ------>MotionEvent

2)Android是如何响应手机的按键操作呢?

    ------->KeyEvent(对KeyEvent一点都不清楚就点我哦)

2、屏幕控制(MotionEvent)机制

1)事件类型:

    down

    move

    up

2)事件发生的顺序:

    down --> move --> move -->...-->up

3)API:

a、MotionEvent: 触屏事件

        int ACTION_DOWN = 0 :代表down

        int ACTION_MOVE = 1 :代表move

        int ACTION_MOVE =2: 代表up

        getAction :得到事件类型值

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

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

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

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

b、Activity

        boolean  dispatch TouchEvent(MotionEvent event) :分发事件

        boolean on TouchEvent(MotionEvent event) 处理事件的回调

c、View

        boolean  dispatchTouchEvent(MotionEvent event) :分发事件

        boolean on TouchEvent(MotionEvent event) 处理事件的回调

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

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

        void setOnLongClickListener(OnLongclickListener i)  :设置长按监听

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

d、ViewGroup

        boolean  dispatchTouchEvent(MotionEvent event) :分发事件

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

事件:

分发 --->dispatchTouchEvent();

处理--->onTouchEvent(), onTouch()

消费--->处理时间的方法返回 true,  当前事件对象就结束了           

4)事件分发和处理流程

事件流程
3、基础案例应用

拖动图片(MotionEvent)

    a、事件处理

    b、动态给视图进行重新布局定位(左下角、右下角)

    c、动态给视图进行重新布局定位(view.layout(l,t,r,b))

1、首先创建一个MotionEventActivity(可以视为MainActivity)
2、在MotionEventActivity的布局文件中,改为RelativeLayout布局,然后创建一个ImageView

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.zxb.apptest_motionevent.MainActivity"
    tools:layout_editor_absoluteY="81dp"
    tools:layout_editor_absoluteX="0dp">


    <ImageView
        android:id="@+id/iv_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/xz"
        />
</RelativeLayout>

3、在MotionEventActivity中对布局进行初始化

public class MotionEventActivity extends Activity implements View.OnTouchListener {

    private ImageView iv_main;
    private RelativeLayout parentView;
    private int pright, pbottom;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_motion_event);

        //初始化imageview 
        iv_main = (ImageView) findViewById(R.id.iv_main);
        //获取imageview的父容器
        parentView = (RelativeLayout) iv_main.getParent();

        //对imageview设置监听事件
        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:
                if(pright ==0){
                    //得到父视图的right 和 bottom
                    pright = parentView.getRight();
                    pbottom = parentView.getBottom();
                }
                //第一次记录lastX,lastY
                lastX = eventX;
                lastY = eventY;
                break;
            case MotionEvent.ACTION_MOVE:
                //计算事件的偏移
                int dx = eventX - lastX;
                int dy = eventY - lastY;
                //根据事件的偏移来移动imageView
                int left = iv_main.getLeft()+dx;
                int top = iv_main.getTop()+dy;
                int right = iv_main.getRight()+dx;
                int bottom = iv_main.getBottom()+dy;

                if (left<0){
                    right+=-left;
                    left =0;
                }
                if(top<0){
                    bottom+=-top;
                    top = 0;
                }
                if(right>pright){
                    left-=right-pright;
                    right =pright;
                }
                if(bottom>pbottom){
                    top-=bottom-pbottom;
                    bottom =pbottom;
                }
                iv_main.layout(left,top,right,bottom);
                //在次记录lastX,lastY
                lastX = eventX;
                lastY = eventY;
                break;

            default:
                break;
        }
        return true;//所有MotionEvent都交给imageView处理
    }
}

@Android_noob小白一枚,希望各路大神前来指教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值