在事件监听的处理模型中,主要涉及三类对象:
1.事件源(Event Soutce):事件发生的场所,通常就是各个组件,例如按钮、窗口、菜单等。
2.事件(Event):事件封装了界面组件上发生的特定事情(通常就是一次用户操作)。如果程序需要获得界面组件上所发生事件的相关信息,一般通过event对象来取得(如按键事件,event.getKeyCode,匹配事件信息对象时是 KeyEvent.KEYCODE_S、KeyEvent.KEYCODE_W 等)。
3.事件监听器(Event Listener):负责监听事件源所发生的事件,并对各种事件作出相应的响应。
Android为不用的界面组件提供了不同的监听器接口:
View.OnClickListener:单击事件的事件监听器必须实现的接口
View.OnCreateContextMenuListener:创建上下文菜单事件的事件监听器必须实现的接口
View.onFocusChangeListener:焦点改变事件的事件监听器必须实现的接口
View.OnKeyListener:按键事件的事件监听器必须实现的接口
View.OnLongClickListener:长单击事件的事件监听器必须实现的接口
View.OnTouchListener:触摸屏事件的事件监听器必须实现的接口
基于监听的事件处理模型变成步骤如下:
1.获取普通界面组件(事件源),也就是被监听对象。
2.实现事件监听器类。
3.调用事件源的 setXXXListener 方法将事件监听器对象注册给普通组件(事件源)。
例1:内部类作为事件监听器类
EventQS.java
public class EventQs extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取应用程序中的bn按钮
Button bn = (Button) findViewById(R.id.bn);
// 为按钮绑定事件监听器。
bn.setOnClickListener(new MyClickListener()); // ①
}
// 定义一个单击事件的监听器
class MyClickListener implements View.OnClickListener
{
// 实现监听器类必须实现的方法,该方法将会作为事件处理器
@Override
public void onClick(View v)
{
EditText txt = (EditText) findViewById(R.id.txt);
txt.setText("bn按钮被单击了!");
}
}
}
例2:外部类作为事件监听器类(较少见,除非其事件监听器确实需要被多个GUI界面共享,且主要是为了完成某种业务逻辑)
SendSmsListener.java
public class SendSmsListener implements OnLongClickListener
{
private Activity act;
private EditText address;
private EditText content;
public SendSmsListener(Activity act, EditText address
, EditText content)
{
this.act = act;
this.address = address;
this.content = content;
}
@Override
public boolean onLongClick(View source)
{
String addressStr = address.getText().toString();
String contentStr = content.getText().toString();
// 获取短信管理器
SmsManager smsManager = SmsManager.getDefault();
// 创建发送短信的PendingIntent
PendingIntent sentIntent = PendingIntent.getBroadcast(act
, 0, new Intent(), 0);
// 发送文本短信
smsManager.sendTextMessage(addressStr, null, contentStr
, sentIntent, null);
Toast.makeText(act, "短信发送完成", Toast.LENGTH_LONG).show();
return false;
}
}
SendSms.java
public class SendSms extends Activity
{
EditText address;
EditText content;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取页面中收件人地址、短信内容
address = (EditText)findViewById(R.id.address);
content = (EditText)findViewById(R.id.content);
Button bn = (Button)findViewById(R.id.send);
bn.setOnLongClickListener(new SendSmsListener(
this , address, content));
}
}
例3.处理事件的事件监听器类
PlaneView.java
public class PlaneView extends View
{
public float currentX;
public float currentY;
Bitmap plane;
// 定义、并创建画笔
Paint p = new Paint();
public PlaneView(Context context)
{
super(context);
// 定义飞机图片
plane = BitmapFactory.decodeResource(context.getResources(),
R.drawable.plane);
setFocusable(true);
}
@Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
// 绘制飞机
canvas.drawBitmap(plane, currentX, currentY, p);
}
}
PlaneGame.java
public class PlaneGame extends Activity
{
// 定义飞机的移动速度
private int speed = 10;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// 去掉窗口标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
// 全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// 创建PlaneView组件
final PlaneView planeView = new PlaneView(this);
setContentView(planeView);
planeView.setBackgroundResource(R.drawable.back);
// 获取窗口管理器
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
// 获得屏幕宽和高
display.getMetrics(metrics);
// 设置飞机的初始位置
planeView.currentX = metrics.widthPixels / 2;
planeView.currentY = metrics.heightPixels - 40;
// 为draw组件键盘事件绑定监听器
planeView.setOnKeyListener(new OnKeyListener()
{
@Override
public boolean onKey(View source, int keyCode, KeyEvent event)
{
// 获取由哪个键触发的事件
switch (event.getKeyCode())
{
// 控制飞机下移
case KeyEvent.KEYCODE_S:
planeView.currentY += speed;
break;
// 控制飞机上移
case KeyEvent.KEYCODE_W:
planeView.currentY -= speed;
break;
// 控制飞机左移
case KeyEvent.KEYCODE_A:
planeView.currentX -= speed;
break;
// 控制飞机右移
case KeyEvent.KEYCODE_D:
planeView.currentX += speed;
break;
}
// 通知planeView组件重绘
planeView.invalidate();
return true;
}
});
}
}
例4.匿名内部类作为事件监听器类(常用模式)
AnonymousListener.java
public class AnonymousListener extends Activity
{
EditText show;
Button bn;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (EditText) findViewById(R.id.show);
bn = (Button) findViewById(R.id.bn);
// 直接使用Activity作为事件监听器
bn.setOnClickListener(new OnClickListener()
{
// 实现事件处理方法
@Override
public void onClick(View v)
{
show.setText("bn按钮被单击了!");
}
});
}
}
例5.Activity本身作为事件监听器
ActivityListener.java
public class ActivityListener extends Activity
implements OnClickListener
{
EditText show;
Button bn;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (EditText) findViewById(R.id.show);
bn = (Button) findViewById(R.id.bn);
// 直接使用Activity作为事件监听器
bn.setOnClickListener(this);
}
// 实现事件处理方法
@Override
public void onClick(View v)
{
show.setText("bn按钮被单击了!");
}
}
例6.直接绑定到标签
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="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
>
<EditText
android:id="@+id/show"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:editable="false"
android:cursorVisible="false"
/>
<!-- 在标签中为按钮绑定事件处理方法 -->
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="单击我"
android:onClick="clickHandler"
/>
</LinearLayout>
BindingTag.xml
public class BindingTag extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
// 定义一个事件处理方法
// 其中source参数代表事件源
public void clickHandler(View source)
{
EditText show = (EditText) findViewById(R.id.show);
show.setText("bn按钮被单击了");
}
}