Android事件处理之一 基于监听的事件处理

本文深入讲解了Android中的事件处理机制,包括监听回调和基于回调的处理模型。详细介绍了监听处理模型中的关键对象——事件源、事件及事件监听器,并演示了如何通过示例代码实现事件监听器。此外,还探讨了不同类型的事件监听器及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本章要点
  • 基于监听的事件处理模型
  • 事件与事件监听接口
  • 实现事件监听器的方式
  • 基于回调的事件处理模型
  • 基于回调的事件传播
  • 常见的事件回调方法
  • 响应系统设置的事件
  • 重写onConfigurationChanged方法响应系统设置更改
  • Handler类功能与用法
  • 使用Handler更新程序界面
  • Handler、Looper、MessageQueue工作原理
  • 异步任务的功能与用法
Android事件处理有两套机制:
  1. 监听
  2. 回调
回调处理代码简洁,常处理通用性事件;某些事件无法使用回调处理,只能监听处理

3.2 监听处理
3.2.1 处理模型
模型中涉及以下三类对象:
EventSource
事件发生源(各组件)
Event
通常是用户一次操作,一般通过Event对象来获得所发生事件的相关信息
EventListener
负责监听事件源发生的事件,并对各种事件做出相应响应
基于监听事件处理模型的编程步骤如下:
  1. 获取事件源
  2. 实现事件监听器,该监听器是一个特殊的Java类,必须实现一个XxxListener
  3. 调用事件源的setXxxListener方法将事件监听器对象注册给事件源
监听器处理有以下规则:
  • 事件源(任何组件都可以作为事件源)
  • 事件监听器:监听器类必须有程序员实现
  • 注册监听器:调用setXxxListener即可


3.2.2 事件和事件监听器
实现监听器是核心
对于包含大量信息的事件,Android同样会将事件信息封装成XxxEvent对象,并把该对象作为参数传入事件处理器
示例程序代码:(飞机移动程序)
plane.java
public class PlaneView extends View{
public float currentX;
public float currentY;
Bitmap
plane;
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);
Paint p =
new Paint();
canvas.drawBitmap(
plane, currentX, currentY, p);
}
}
main.java
public class MainActivity extends ActionBarActivity {
private int speed = 10;
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        requestWindowFeature(Window.
FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.
FLAG_FULLSCREEN,
        WindowManager.LayoutParams.
FLAG_FULLSCREEN);
       
final PlaneView planeView = new PlaneView(this);
        setContentView(planeView);
        planeView.setBackgroundResource(R.drawable.
back);
       
windowManager = getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics metrics =
new DisplayMetrics();
        display.getMetrics(metrics);
        planeView.
currentX = metrics.widthPixels / 2;
        planeView.
currentY = metrics.heightPixels - 40;
        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;
       
default:
       
break;
        }
        planeView.invalidate();
       
return true;
        }
        });
    }
}
对应不同组件,Android提供了不同的接口,这些接口以内部类形式存在,以View类为例:

View.OnClickListener
单击事件的事件监听器必须实现的接口
View.OnCreateContextMenuListener
创建上下文菜单事件的事件监听器
View.onFocusChangeListener

View.OnKeyListener

View.OnLongClickListener
长单击
View.OnTouchListener
触摸屏幕
在程序中实现事件监听器:
  • 内部类
  • 外部类
  • Activity本身
  • 匿名内部类


3.2.3 内部类


3.2.4 外部类
使用外部类比较少见,因为
  • 事件监听器通常属于特定GUI界面
  • 外部类不能自由访问GUI界面中的组件
但如果某个事件监听器需要被多个GUI界面共享,而且主要是实现业务逻辑,则可以考虑
发送短信示例代码:
public class MainActivity extends ActionBarActivity {

EditText
address;
EditText
content;
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_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));
       
    }
}
send class
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 sentIntent = PendingIntent.getBroadcast(
act,0,new Intent(), 0);
smsManager.sendTextMessage(addressStr,
null, contentStr, sentIntent, null);
Toast.makeText(
act, "sms sent", Toast.LENGTH_SHORT).show();
return false;
}
}

3.2.5 Activity本身作为事件监听器
这种方法使用Activity本身作为监听器,可以直接在Activity类中定义事件处理器方式,这种方式虽然简洁,但有两个明显缺点:
  1. 可能会造成程序结构混乱
  2. 用法不伦不类


3.2.6 匿名内部类 作为事件监听器
大部分事件处理器都没有复用价值。所以使用匿名内部类更合适,实际上这种形式是目前使用最广泛的事件监听器
示例代码:
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
       
show = (EditText) findViewById(R.id.show);
       
bn = (Button) findViewById(R.id.bn);
       
bn.setOnClickListener(new OnClickListener()
        {
       
@Override
       
public void onClick(View v)
        {
       
show.setText("button click;");
        }
        });
    }

3.2.7 直接绑定到标签
Android还有一种更简单的绑定事件监听器的方式,直接在界面布局中为制定标签绑定处理方式
对于很多Android界面组件标签而言,他们都支持onClick属性,该属性的属性值就是一个形如xxx(View source)的方法
    <Button
       
android:id="@+id/bn"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="press me"
        android:onClick="clickHandler"/>
Java代码:
public void clickHandler(View source)
{
EditText show = (EditText) findViewById(R.id.
show);
show.setText(
"button onClick clickHandler");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值