Andorid事件处理
在Andorid中已经很完善的包装了关于事件处理的方式,主要有两套机制:
- 基于监听的事件处理
- 基于回调的事件处理
对于Android基于回调的时间处理来说: 主要做法重写Andorid组件特定的回调方法。Android中已经为大部分界面控件提供了回调方法,调用就好。
对于Android监听的事件处理而言,就是我们经常遇到的组件绑定的事件监听器。
这篇文章主要写关于监听的事件处理,回调机制会在下篇介绍
- 监听机制下的处理模型
这里主要有三类对象:
- Event Source 事件源:事件的发生场所,比如按钮,输入框,菜单等。
- Event 事件:指的是在事件源上发生的特定的操作。
- Event Listener 事件监听器:负责监听事件源的发生,并且做出响应。
监听事件流程图:
备注:事件处理就是指系统响应。
基于监听的事件处理模型的编程步骤如下:
- 获取普通界面组件(事件源),也就是被监听的对象。
- 实现事件监听器,一个Java类,这个类中要实现一个XxxListener接口。
- 设置事件源setXxxListener方法,并且注册给组件(事件源)。
Android中已经对事件源,和事件做出了很大的简化:任何组件都可以作为事件源,事件的产生我们不用关心,要做的就是核心部分,实现事件监听器。Android会将事件封装成XxxEvent对象并且传送给事件处理器。
在事件监听的处理模型中,程序必须事件事件监听接口! Andorid为不同的组件提供了不同的接口
我们用的比较多的View(我在初学阶段遇到全是这部分的)中有下面几个:
View.OnClickListener
单击事件监听器必须实现的接口
View.OnCreateContextMenuListener
创建上下文菜单事件
View.OnFocusChangeListener
焦点改变事件
View.OnKeyListener
按键事件监听器
View.OnLongClickListener
长按事件监听器
View.OnTouchListener
触摸屏事件监听器
在实现特点的事件监听器接口中有一下几种方式:
- 内部类:将事件监听器定义成当前类的内部类
- 外部类:将事件监听器定义成一个外部的类
- Activity:这种做法用不多,在Activity自己实现监听器接口
- 匿名内部类:我自己用的比较多的方法,用匿名内部类来实现监听器接口
接下来介绍这四种方式
内部类方式实现监听器
首先是一个很简单的布局文件avtivity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="New Buntton"
android:id="@+id/button" />
</LinearLayout>
然后是MainActivity.java文件,很简单
public class MainActivity extends Activity {
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.avtivity_main);
bt=(Button) findViewById(R.id.button);
bt.setOnClickListener(new MyClickListener);
}
class MyClickListener implements View.OnClickListener{
@Override
public void onClick(View v){
Log.i("tag","内部类实现事件监听器");
Toast.makeText(MainActivity.this, "内部类实现事件监听器", Toast.LENGTH_SHORT).show();
}
}
}
外部类方式实现监听器
同样还是上面个xml布局文件
//外部类的监听写法
public class MainActivity extends AppCompatActivity{
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//外部类实现监听
bt = (Button) findViewById(R.id.button);
bt.setOnClickListener(new MyOnClickListener());
}
}
接着是另一个java文件 MyOnClickListener.java
//这里是一个外部类 父类
class MyOnClickListener implements View.OnClickListener{
@Override
public void onClick(View view){
Log.i("tag","外部事件调用");
Toast.makeText(MyOnClickListener.this, "外部类实现", Toast.LENGTH_SHORT).show();
}
}
Activity本身作为事件监听器
同样很简单,调用setOnClickListener() 函数的时候用当前Activity作为参数(this)传入,然后在后面补上事件的实现方法就行
public class MainActivity extends AppCompatActivity{
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt = (Button) findViewById(R.id.button);
//直接使用Activity作为事件监听器
bt.setOnClickListener(this);
}
//实现事件处理方法
@Override
public void OnClick(View v){
Log.i("tag","本身作为事件监听器");
Toast.makeText(MyOnClickListener.this, "Activity本身作为事件监听器", Toast.LENGTH_SHORT).show();
}
}
匿名内部类作为事件监听器
这种方法相比较之前的几种方法的好处就是编写方便,在大多数时候我推荐大家用这种方法写监听器。
大部分时候事件处理器都没有什么复用价值,为了更好的符合软件工程思想(低耦合,高内聚),这种监听器的书写方式,多多益善。
public class MainActivity extends AppCompatActivity{
private Button bt;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//findViewById用来联系控件button和代码
bt = (Button) findViewById(R.id.button);
//设置button的监听器 通过监听器实现操作 匿名内部类来实现监听
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//这里监听 onClick
Log.i("tag","匿名内部类实现事件的监听");
Toast.makeText(MyOnClickListener.this, "匿名内部类实现", Toast.LENGTH_SHORT).show();
}
});
}
}
大家可以看到在匿名内部类当中是没有类名的,直接new了一个新的对象,并且在后面实现接口OnClickListener()。这是Java上的语法,不太容易掌握,但是原理上来说是非常简单的,强推。
彩蛋~ 直接绑定到标签
第五种方法~,这种方法用的不多,知道下就好。。。。
原理是在布局文件中直接绑定一个标签属性
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="New Buntton"
android:id="@+id/button"
android:onClick="clickButton"/>
</LinearLayout>
在Button按钮的属性中多了一个onClick标签,并且绑定了函数clickButton,接下来只要实现这个函数,在触发事件的时候会自动调用这个函数
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//定义上文中的函数
//这里source代表事件源
public void clickButton(View source){
Log.i("tag","通过绑定标签实现事件的监听");
Toast.makeText(MyOnClickListener.this, "标签方法", Toast.LENGTH_SHORT).show();
}
}
好吧,第五种方法我个人是非常少用到的,好处和坏处我也说不上来,不太喜欢用他
这边监听器实现的事件处理方式就已经全部说完了,下一篇要说的是基于回调的事件处理