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

本章要点
  • 基于监听的事件处理模型
  • 事件与事件监听接口
  • 实现事件监听器的方式
  • 基于回调的事件处理模型
  • 基于回调的事件传播
  • 常见的事件回调方法
  • 响应系统设置的事件
  • 重写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" );
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值