在Andorid中已经很完善的包装了关于事件处理的方式,主要有两套机制:
基于监听的事件处理基于回调的事件处理对于Android基于回调的时间处理来说: 主要做法重写Andorid组件特定的回调方法。Android中已经为大部分界面控件提供了回调方法,调用就好。
对于Android监听的事件处理而言,就是我们经常遇到的组件绑定的事件监听器。 这篇文章主要写关于监听的事件处理,回调机制会在下篇介绍
- 监听机制下的处理模型 这里主要有三类对象: - Event Source 事件源:事件的发生场所,比如按钮,输入框,菜单等。 - Event 事件:指的是在事件源上发生的特定的操作。 - Event Listener 事件监听器:负责监听事件源的发生,并且做出响应。
监听事件流程图:
Created with Raphaël 2.1.0 外部动作 事件源 事件 事件监听器 事件处理器备注:事件处理就是指系统响应。
基于监听的事件处理模型的编程步骤如下:
获取普通界面组件(事件源),也就是被监听的对象。实现事件监听器,一个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(); } }好吧,第五种方法我个人是非常少用到的,好处和坏处我也说不上来,不太喜欢用他
这边监听器实现的事件处理方式就已经全部说完了,下一篇要说的是基于回调的事件处理