在事件监听的处理模型中,主要涉及三类对象:

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按钮被单击了");
	}
}