Android事件
基于监听的事件处理
事件源:事件发生的产所,一般为各个控件
事件:在事件源上发生的事情,如单击,双击等等
事件监听器:负责监听事件源发生的事件,并对各种事件进行响应
基于监听的事件处理是一种委派式的事件处理方式,在这种处理方式中,事件源将整个事件处理委托给事件监听器进行处理,事件监听器调用相应的方法进行处理。委派式的处理方式将事件源和事件监听器进行分离,从某种程度上来说提高了程序的可读性。
基于内部类的事件监听方式
在类内部写一个监听器类,并实现监听接口。如下所示:
public ListenerTest extends AppActivity {
private Button btn;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new MyListensr());
}
class MyListensr implements View.OnClickListener {
@Override
public void OnClick (View v) {
//事件处理操作
}
}
}
基于外部类的事件监听方式
有的时候当一个监听器需要被多个活动使用时,可以通过基于外部类的事件监听方式进行事件处理。如下所示
public ListenerTest extends AppActivity {
private Button btn;
private EditText address;
private EditText content;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
address = findViewById(R.id.address);
content = findViewById(R.id.content);
btn.setOnClickListener(new MyListensr(this, address, content));
}
}
public MyListensr implements View.OnClickListener {
private Activity activity;
private EditText address;
private EditText content;
public MyListensr (Activity activity, EditText address, EditText content) {
this.activity = activity;
this.address = address;
this.content = content;
}
@Override
public void OnClick (View v) {
//事件处理操作
}
}
基于匿名内部类的事件监听方式
基于匿名内部类的方式使用最广泛,其使用到了java中的匿名内部类的语法。如下所示:
public ListenerTest extends AppActivity {
private Button btn;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//事件处理操作
}
});
}
}
基于接口实现或Activity自身响应
这种方式直接使用Activity作为监听器类,从而直接在活动中添加事件处理方法。如下所示:
public ListenerTest extends AppActivity implements View.OnClickListener{
private Button btn;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickener(this);
}
@Override
public void onClick (View v) {
switch(v.getId()) {
case R.id.btn:
//事件处理操作
break;
default:
break;
}
}
}
绑定到标签
通过UI布局,直接在UI布局中,设定其事件,如Android:OnClick,Android:On
LongClick等等。如下所示,在清单文件中添加一个Button
<Button
android:id="@+id/btn"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:onClick = "function"
/>
在活动中定义该事件处理方法:
public ListenerTest extends AppActivitym {
private Button btn;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
}
public void function (View v) {
//事件处理操作
}
}
基于回调的事件处理
通过对基于监听的事件处理方式得知,基于监听的是将事件源与事件监听器分开。这里要讲的基于回调的事件处理是Android中另外一种事件处理方式,其与基于监听的事件处理方式截然相反。在基于回调的事件处理中事件源和事件监听均数据一个整体中的,相当于事件源和事件监听属于一个控件。其实现方式就是定义一个控件类并继承View 的控件类,此外,还需要重写父类中的事件处理方法。
Android 的View类中提供了许多事件处理方法,如下所示:
- boolean onKeyDown(int keyCode, KeyEvent event):当用于在该控件按下时触发该方法
- boolean onKeyLongPress(int keyCode, KeyEvent event):当用户长按控件时触发该方法
- boolean onKeyUp(int keyCode, KeyEvent event):当用户在控件上按下后松开按键时触发该方法
除上面之外,还有许多事件处理方法,下面举例说明。
public MyButton extends Button {
public MyButton () {
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
super.onKeyDown(keyCode, event);
Log.d(TAG,"onKeyDown");
//如果返回true,表明该事件不会向外扩散了
return true;
}
}
在清单文件直接使用
<com.android.example.MyButton
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"
android:text = "test"
android:id = "@+id/btn"
/>
通过上述例子可以看出onKeyDown返回了一个boolean值,其实在基于回调的事件处理中的大多数事件处理方法都会返回boolean值,该返回值得意义如下:
- 如果返回true,表明该方法已经完全处理该事件,该事件不会传出去了
- 如果返回false,表明该方法并没有完全处理该事件,该事件会传出去
public ListenerTest extends AppActivity{
private Button btn;
@Override
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.main);
btn = (Button)findViewById(R.id.btn);
btn.setOnClickener(new View.onClickListener{
@override
public boolean onKey (View v, int keyCode, KeyEvent event) {
//事件处理操作
Log.d(TAG,"onKey");
return false;
}
});
}
@Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
super.onKeyDown (keyCode, event);
//事件处理操作
Log.d(TAG,"onKeyDown");
return true;
}
}
上述例子中,可以看出所有的事件处理方法中,都返回false,所以这些方法都没有完全处理该事件,意味着事件会被传播。在这种情况下,最先触发的是按键上绑定的事件处理方法,接着触发该控件类提供的回调方法,最后调用该活动提供的事件处理方法。