Android 中的事件处理

当用户在应用界面上执行各种操作时, 应用程序需要为用户的动作提供响应, 这种响应的过程就是事件处理.

事件处理:
	1. 基于监听的事件处理机制.
	2. 基于回调的事件处理机制.

1. 基于监听的事件处理机制

监听三要素:

  1. Event Source (事件源)
  2. Event (事件)
  3. Event Listener (事件监听器)

实现监听事件的方法:

  1. 通过内部类实现.
  2. 通过匿名内部类实现.
  3. 通过事件源所在类实现.
  4. 通过外部类实现.
  5. 布局文件中 OnClick 属性 (针对点击事件).

通过内部类实现

package com.example.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.example.hello.util.ToastUtil;

public class EventActivity extends AppCompatActivity {
    
    

    private Button btnEvent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        btnEvent = findViewById(R.id.btn_event);
        // 通过内部类实现
        btnEvent.setOnClickListener(new OnClick());
    }

    class OnClick implements View.OnClickListener {
    
    
        
        @SuppressLint("NonConstantResourceId")
        @Override
        public void onClick(View v) {
    
    
            switch (v.getId()) {
    
    
                case R.id.btn_event:
                    ToastUtil.showShortToast(EventActivity.this, "通过内部类实现");
                    break;
                default:
                    throw new IllegalStateException("Unexpected value: " + v.getId());
            }
        }
    }
}

通过匿名内部类实现

package com.example.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;

import com.example.hello.util.ToastUtil;

public class EventActivity extends AppCompatActivity {
    
    

    private Button btnEvent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        btnEvent = findViewById(R.id.btn_event);
        // 通过匿名内部类实现
        btnEvent.setOnClickListener(v -> {
    
    
            ToastUtil.showShortToast(EventActivity.this, "通过匿名内部类实现");
        });
    }

}

通过事件源所在类实现

package com.example.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.example.hello.util.ToastUtil;

public class EventActivity extends AppCompatActivity implements View.OnClickListener {
    
    

    private Button btnEvent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        btnEvent = findViewById(R.id.btn_event);
    }

    /**
     * 通过事件源所在类实现
     *
     * @param v view
     */
    @SuppressLint("NonConstantResourceId")
    @Override
    public void onClick(View v) {
    
    
        switch (v.getId()) {
    
    
            case R.id.btn_event:
                ToastUtil.showShortToast(EventActivity.this, "通过事件源所在类实现");
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + v.getId());
        }
    }
}

通过外部类实现

先建立一个类

package com.example.hello.util;

import android.app.Activity;
import android.view.View;

public class EventUtil implements View.OnClickListener {
    
    

    private Activity activity;
    private String content;

    public EventUtil(Activity activity, String content) {
    
    
        this.activity = activity;
        this.content = content;
    }

    @Override
    public void onClick(View v) {
    
    
        ToastUtil.showShortToast(activity, content);
    }
}

package com.example.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;

import com.example.hello.util.EventUtil;

public class EventActivity extends AppCompatActivity {
    
    

    private Button btnEvent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        btnEvent = findViewById(R.id.btn_event);
        // 通过外部类实现
        btnEvent.setOnClickListener(new EventUtil(EventActivity.this, "通过外部类实现"));
    }

}

布局文件中 OnClick 属性 (针对点击事件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".EventActivity">

    <Button
        android:id="@+id/btn_event"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="showEvent"
        android:text="@string/event" />

</LinearLayout>
package com.example.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;

import com.example.hello.util.ToastUtil;

public class EventActivity extends AppCompatActivity {
    
    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
    }

    /**
     * 布局文件中 OnClick 属性 (针对点击事件)
     *
     * @param view v
     */
    @SuppressLint("NonConstantResourceId")
    public void showEvent(View view) {
    
    
        switch (view.getId()) {
    
    
            case R.id.btn_event:
                ToastUtil.showShortToast(EventActivity.this, "布局文件中 OnClick 属性 (针对点击事件)");
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + view.getId());
        }
    }
}

这几种方法中没有优先级的概念, 哪一个是最后设置就只执行哪一个. 其中布局的方法是最先加载的, 所以是最先设置的.

2. 基于回调的事件处理机制

回调机制与监听机制的区别: 回调机制中事件源与事件监听是绑在一起的.
基于事件的传播.

自定义一个 Button

package com.example.hello.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import androidx.appcompat.widget.AppCompatButton;

public class MyButton extends AppCompatButton {
    
    

    public MyButton(Context context) {
    
    
        super(context);
    }

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

    public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
    
    
        super(context, attrs, defStyleAttr);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
    
        super.onTouchEvent(event);
        switch (event.getAction()) {
    
    
            case MotionEvent.ACTION_DOWN:
                Log.d("MyButton", "---onTouchEvent:ACTION_DOWN---");
                break;
            case MotionEvent.ACTION_UP:
                Log.d("MyButton", "---onTouchEvent:ACTION_UP---");
                break;
        }
        return false;
    }
}

在布局中添加 MyButton

    <com.example.hello.widget.MyButton
        android:id="@+id/btn_myButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/event" />

EventActivity 设置 MyButton.

package com.example.hello;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;

import com.example.hello.widget.MyButton;

public class EventActivity extends AppCompatActivity {
    
    

    private MyButton myButton;

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event);
        myButton = findViewById(R.id.btn_myButton);
        myButton.setOnTouchListener((v, event) -> {
    
    
            switch (event.getAction()) {
    
    
                case MotionEvent.ACTION_DOWN:
                    Log.d("EventActivityListener", "---onTouchEvent:ACTION_DOWN---");
                    break;
            }
            return false;
        });
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    
    
        switch (event.getAction()) {
    
    
            case MotionEvent.ACTION_DOWN:
                Log.d("EventActivity", "---onTouchEvent:ACTION_DOWN---");
                break;
        }
        return false;
    }
}

在这里插入图片描述

从日志打印可以看出监听优于回调.

return false; 代表继续向外传播.
return true; 代表停止向外传播.

猜你喜欢

转载自blog.csdn.net/YKenan/article/details/113681358
今日推荐