基于监听的事件处理机制模型
流程模型图:
- 事件监听机制中由事件源,事件,事件监听器三类对象组成 ,处理流程如下:
- Step 1:为某个事件源(组件)设置一个监听器,用于监听用户操作
- Step 2:用户的操作触发了事件源的监听器
- Step 3:生成了对应的事件对象
- Step 4:将这个事件源对象作为参数传给事件监听器
- step 5:事件监听器对事件对象进行判断,执行对应的事件处理器(对应事件的处理方法)
- 事件监听机制是一种委派式的事件处理机制,事件源(组件)事件处理委托给事件监听器,当事件源发生指定事件时,就通知指定事件监听器执行相应的操作
- 实现事件监听的方式主要有如下几种
使用匿名内部类
- 直接 setXxxListener ,重写接口里面的方法即可,通常是临时使用一次,复用性不高!
- 上图所示效果,布局文件 activity_main.xml 内容如下:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/btnOne"
android:layout_width="match_parent"
android:layout_height="64dp"
android:text="按 钮"
android:textColor="#001D25"
android:textSize="20dp" />
</android.support.constraint.ConstraintLayout>
- MainAcivity.java 实现代码如下:
package com.example.administrator.helloworld;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.Date;
/**
* 一个应用程序可以有1个或多个活动,而没有任何限制。
* 每个为应用程序所定义的活动都需要在 AndroidManifest.xml 中声明,应用的主活动的意图过滤器标签中需要包含 MAIN 动作和 LAUNCHER 类别
* 如果 MAIN 动作还是 LAUNCHER 类别没有在活动中声明,那么应用程序的图标将不会出现在主屏幕的应用列表中。
*/
public class MainActivity extends AppCompatActivity {
/**
* 当活动第一次被创建时调用
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 从项目的 res/layout 中的XML文件加载 UI 组件
* android.util.Log#d(java.lang.String, java.lang.String) 方法用于在 Logcat 窗口中打印日志
*/
setContentView(R.layout.activity_main);
Log.d("Android Message:", "The onCreate() event");
/** 为 按钮绑定单击事件
* 就和 js 中为某个 id 的标签绑定事件差不多
*/
Button button = findViewById(R.id.btnOne);
button.setOnClickListener(new View.OnClickListener() {
/**重写点击事件的处理方法onClick()
* 显示 Toast 信息,这个消息会显示到用户界面上,短暂显示后会消失
* */
@Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "你点击了按钮:" + new Date().toString(), Toast.LENGTH_SHORT).show();
}
});
}
}
使用内部类
- 其实原理和上面大同小异,使用内部类可以在该类中进行复用,可直接访问外部类的所有界面组件!
- 布局文件仍会和上面的一致, MainActivity 类代码如下:
package com.example.administrator.helloworld;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.util.Date;
/**
* 一个应用程序可以有1个或多个活动,而没有任何限制。
* 每个为应用程序所定义的活动都需要在 AndroidManifest.xml 中声明,应用的主活动的意图过滤器标签中需要包含 MAIN 动作和 LAUNCHER 类别
* 如果 MAIN 动作还是 LAUNCHER 类别没有在活动中声明,那么应用程序的图标将不会出现在主屏幕的应用列表中。
*/
public class MainActivity extends AppCompatActivity {
Button button = null;
/**
* 当活动第一次被创建时调用
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 从项目的 res/layout 中的XML文件加载 UI 组件
* android.util.Log#d(java.lang.String, java.lang.String) 方法用于在 Logcat 窗口中打印日志
*/
setContentView(R.layout.activity_main);
Log.d("Android Message:", "The onCreate() event");
/** 为 按钮绑定单击事件
* 就和 js 中为某个 id 的标签绑定事件差不多
*/
button = findViewById(R.id.btnOne);
button.setOnClickListener(new BtnClickListener());
}
/**
* 定义一个内部类,实现 View.OnClickListener 接口,并重写 onClick() 方法
*/
class BtnClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
CharSequence buttonText = button.getText();
Toast.makeText(getApplicationContext(), buttonText + " 被点击了", Toast.LENGTH_SHORT).show();
}
}
}
- 同理也可以将它写成外部类,不再累述
implements View. OnClickListener
- 方法都是大同小异,实现如下功能,点击 “播放”按钮后,开始播放手机上的 mp3 音乐;点击 “暂停” 按钮后,暂停音乐播放,点击“退出”按钮后,重置音乐,即回到初始位置,等待播放。
- 播放 mp3 时,即使当前 Activity 被覆盖,在后台照样会播放。
- 布局文件 activity_main.xml 内容如下:
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/GridLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:columnCount="1"
android:orientation="horizontal"
android:rowCount="3">
<Button
android:id="@+id/btnStart"
android:layout_width="match_parent"
android:layout_height="64dp"
android:text="播放" />
<Button
android:id="@+id/btnStop"
android:layout_width="match_parent"
android:layout_height="64dp"
android:text="暂停" />
<Button
android:id="@+id/btnQuit"
android:layout_width="match_parent"
android:layout_height="64dp"
android:text="退出" />
</GridLayout>
- MainActivity.java 内容如下:
package com.example.administrator.helloworld;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
/**
* 一个应用程序可以有1个或多个活动,而没有任何限制。
* 每个为应用程序所定义的活动都需要在 AndroidManifest.xml 中声明,应用的主活动的意图过滤器标签中需要包含 MAIN 动作和 LAUNCHER 类别
* 如果 MAIN 动作还是 LAUNCHER 类别没有在活动中声明,那么应用程序的图标将不会出现在主屏幕的应用列表中。
* implements View.OnClickListener:用于绑定单击事件
*/
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
/**
* TAG:Log.d(String tag, String msg) 的消息标签
* btn_play:播放按钮
* btn_stop:暂停按钮
* btn_quit:退出重置按钮
* isRelease:判断 MediaPlayer 是否释放的标志
*/
private static final String TAG = "MainActivity : ";
private Button btn_play;
private Button btn_stop;
private Button btn_quit;
private MediaPlayer mPlayer = null;
private boolean isRelease = true;
/**
* 当活动第一次被创建时调用
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 从项目的 res/layout 中的XML文件加载 UI 组件
* android.util.Log#d(java.lang.String, java.lang.String) 方法用于在 Logcat 窗口中打印日志
*/
setContentView(R.layout.activity_main);
Log.d(TAG, "The onCreate(Bundle savedInstanceState) .....");
bindViews();
}
/**
* 为按钮 绑定单击事件
*/
private void bindViews() {
btn_play = findViewById(R.id.btnStart);
btn_stop = findViewById(R.id.btnStop);
btn_quit = findViewById(R.id.btnQuit);
btn_play.setOnClickListener(this);
btn_stop.setOnClickListener(this);
btn_quit.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Log.d(TAG, "-----------" + v.getId());
switch (v.getId()) {
case R.id.btnStart:
/**如果当前 MediaPlayer 未关联播放的文件,则进行关联
* 播放的是 res/raw 目录下的 day_by_day.mp3 文件
*/
if (isRelease) {
mPlayer = MediaPlayer.create(this, R.raw.day_by_day);
isRelease = false; //设置标识
}
mPlayer.start(); //开始播放
btn_play.setEnabled(false); //禁用播放按钮
btn_stop.setEnabled(true); //启用暂停按钮
btn_quit.setEnabled(true); //启用退出按钮
break;
case R.id.btnStop:
mPlayer.pause(); //停止播放
btn_play.setEnabled(true); //启用播放按钮
btn_stop.setEnabled(false); //禁用暂停按钮
btn_quit.setEnabled(false); //禁用退出按钮
break;
case R.id.btnQuit:
mPlayer.reset(); //重置MediaPlayer
mPlayer.release(); //释放MediaPlayer,即释放与此媒体播放器对象关联的资源。
isRelease = true; //设置标识
btn_play.setEnabled(true); //启用播放按钮
btn_stop.setEnabled(false); //禁用暂停按钮
btn_quit.setEnabled(false); //禁用退出按钮
break;
}
}
}