基于监听的事件处理机制


前言:


我们开发的app更多的时候是需要与用户的交互----即对用户的操作进行响应

这就涉及到了android的事件处理机制;

android给我们提供了两套功能强大的处理机制:

①基于监听的事件处理机制

②基于回调的事件处理机制

在这一节中,我们会先介绍一下基于监听的事件处理机制

好了,废话不多说!



我们要先了解一下监听处理机制的模型


监听的处理模型:

处理模型图:




文字表述:

事件监听机制中由事件源,事件,事件监听器三类对象组成

处理流程:

step 1:为某个事件源(组件)设置一个监听器,用于监听用户操作

step 2:用户的操作,触发了事件源的监听器

step 3:生成了对应的事件对象

step 4:将这个事件源对象作为参数传给事件监听器

step 5:事件监听器对事件对象进行判断,执行对应的事件处理器(对应事件的处理方法)


归纳:

事件监听机制是一种委派式的事件处理机制,事件源(组件)事件处理委托给事件监听器

当事件源发生制定事件时,就通知事件监听器,执行相应的操作



使用形式:


实例:

这里实现的是点击按钮后,显示toast信息提示

为了演示,以下是用不同的形式实现如图的效果,可仔细揣摩代码


效果图:




①直接使用匿名内部类,作为事件监听器

ps:就是我们平时最常用的那种,setXxxListener后就重写里面的对应方法

通常都是临时使用一次,复用性不高



代码:

xml就是一个普通的按钮,这就不给出了

MainActivity.java


[java]  view plain copy
  1. package com.jay.example.innerlisten;  
  2.   
  3. import android.os.Bundle;  
  4. import android.view.View;  
  5. import android.view.View.OnClickListener;  
  6. import android.widget.Button;  
  7. import android.widget.Toast;  
  8. import android.app.Activity;  
  9.   
  10.   
  11. public class MainActivity extends Activity {  
  12.   
  13.     private Button btnshow;  
  14.       
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.           
  20.         btnshow = (Button) findViewById(R.id.btnshow);  
  21.         btnshow.setOnClickListener(new OnClickListener() {  
  22.             //重写点击事件的处理方法onClick()  
  23.             @Override  
  24.             public void onClick(View v) {  
  25.                 //显示Toast信息  
  26.                 Toast.makeText(getApplicationContext(), "你点击了按钮", Toast.LENGTH_SHORT).show();  
  27.             }  
  28.         });  
  29.     }      
  30. }  


②使用内部类作为事件监听器

这里和上面的匿名内部类不一样的哦

使用优点:可以在该类中复用,可直接访问外部类的所有界面组件


代码:

[java]  view plain copy
  1. package com.jay.example.innerlisten;  
  2.   
  3. import android.os.Bundle;  
  4. import android.view.View;  
  5. import android.view.View.OnClickListener;  
  6. import android.widget.Button;  
  7. import android.widget.Toast;  
  8. import android.app.Activity;  
  9.   
  10.   
  11. public class MainActivity extends Activity {  
  12.   
  13.     private Button btnshow;  
  14.       
  15.     @Override  
  16.     protected void onCreate(Bundle savedInstanceState) {  
  17.         super.onCreate(savedInstanceState);  
  18.         setContentView(R.layout.activity_main);  
  19.           
  20.         btnshow = (Button) findViewById(R.id.btnshow);  
  21.         //直接new一个内部类对象作为参数  
  22.         btnshow.setOnClickListener(new BtnClickListener());  
  23.           
  24.     }   
  25.       
  26.       
  27.     //定义一个内部类,实现View.OnClickListener接口,并重写onClick()方法  
  28.     class BtnClickListener implements View.OnClickListener  
  29.     {  
  30.         @Override  
  31.         public void onClick(View v) {  
  32.               
  33.             Toast.makeText(getApplicationContext(), "按钮被点击了", Toast.LENGTH_SHORT).show();  
  34.         }  
  35.           
  36.     }  
  37. }  



③使用外部类作为事件监听器

就是另外创建一个处理事件的Java文件,该形式比较少见

因为外部类不能直接访问用户界面类中的组件,要通过构造方法将组件传入使用,

这样的结果就是代码不够简洁


ps:为了演示,这里通过textView代替Toast显示!


效果图:



代码:

布局比较简单,就是一个按钮+文本框,这里不给出了

另外编写一个外部类:

MyClick.java


[java]  view plain copy
  1. package com.jay.example.innerlisten;  
  2.   
  3. import android.view.View;  
  4. import android.view.View.OnClickListener;  
  5. import android.widget.TextView;  
  6.   
  7. public class MyClick implements OnClickListener {  
  8.   
  9.     private TextView textshow;  
  10.     //把文本框作为参数传入  
  11.     public MyClick(TextView txt)  
  12.     {  
  13.         textshow = txt;  
  14.     }  
  15.       
  16.     @Override  
  17.     public void onClick(View v) {  
  18.         //点击后设置文本框显示的文字  
  19.         textshow.setText("点击了按钮!");  
  20.     }  
  21.   
  22. }  


MainActivity.java


[java]  view plain copy
  1. package com.jay.example.innerlisten;  
  2. import android.os.Bundle;  
  3. import android.widget.Button;  
  4. import android.widget.TextView;  
  5. import android.app.Activity;  
  6.   
  7.   
  8. public class MainActivity extends Activity {  
  9.   
  10.     private Button btnshow;  
  11.     private TextView txtshow;  
  12.       
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.activity_main);  
  17.           
  18.         btnshow = (Button) findViewById(R.id.btnshow);  
  19.         txtshow = (TextView) findViewById(R.id.textshow);  
  20.         //直接new一个外部类,并把TextView作为参数传入  
  21.         btnshow.setOnClickListener(new MyClick(txtshow));  
  22.           
  23.     }       
  24. }  



④直接使用Activity作为事件监听器

只需要让Activity类实现~Listener事件监听接口,在Activity中定义重写对应的事件处理器方法

eg:Activity实现了OnclickListener接口,重写onClick(view)方法

当为某组件添加该事件监听器对象时,可以直接setXxxListener(this)即可


效果图:



布局文件略


MainActivity.java

[java]  view plain copy
  1. package com.jay.example.innerlisten;  
  2. import android.os.Bundle;  
  3. import android.view.View;  
  4. import android.view.View.OnClickListener;  
  5. import android.widget.Button;  
  6. import android.widget.Toast;  
  7. import android.app.Activity;  
  8.   
  9. //让Activity方法实现OnClickListener接口  
  10. public class MainActivity extends Activity implements OnClickListener{  
  11.   
  12.     private Button btnshow;  
  13.       
  14.     @Override  
  15.     protected void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.         setContentView(R.layout.activity_main);  
  18.           
  19.         btnshow = (Button) findViewById(R.id.btnshow);  
  20.         //直接写个this  
  21.         btnshow.setOnClickListener(this);  
  22.           
  23.     }  
  24.   
  25.     //重写接口中的抽象方法  
  26.     @Override  
  27.     public void onClick(View v) {  
  28.         Toast.makeText(getApplicationContext(), "点击了按钮", Toast.LENGTH_SHORT).show();          
  29.     }       
  30. }  


⑤直接绑定到标签

如题,就是现在xml布局文件锁对应的Activity中定义一个事件处理方法

eg:public void myclick(View source)    source对应的事件源

接着布局文件中对应要触发事件的组件:设置一个熟悉:onclick = "myclick"即可

例子还是那个点击按钮后提示toast信息


代码:

MainActivity:

[java]  view plain copy
  1. package com.jay.example.caller;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.widget.Toast;  
  7.   
  8.   
  9. public class MainActivity extends Activity {  
  10.   
  11.   
  12.     @Override  
  13.     protected void onCreate(Bundle savedInstanceState) {  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.activity_main);   
  16.     }  
  17.       
  18.     //自定义一个方法,传入一个view组件作为参数  
  19.     public void myclick(View source)  
  20.     {  
  21.         Toast.makeText(getApplicationContext(), "按钮被点击了", Toast.LENGTH_SHORT).show();  
  22.     }  
  23. }  


main.xml:

[html]  view plain copy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:id="@+id/LinearLayout1"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical" >  
  7.       
  8.     <Button   
  9.         android:layout_width="wrap_content"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="按钮"  
  12.         android:onClick="myclick"      
  13.     />  
  14.       
  15. LinearLayout>  

代码解释:

就是先在activity定义一个方法,然后在xml文件中为某个组件设置一个οnclick=“”的属性即可


重要的OnTouchEvent事件解析


之所以在这里讲解下OnTouchEvent事件,并不是单单因为他是事件监听机制的一个例子

而且因为他的调用流程比较特别,同时因为这个事件是我们实际开发中使用得比较多的


所有的view组件都重写了该方法,应用程序可以通过该方法处理手机屏幕的触摸事件。


方法声明:

public boolean  onTouchEvent(MotionEvent event);


使用流程:

①为某个view(组件)setOnTouchListener(new OnTouchListener())

②重写onTouch()方法

③因为有三种比较常用的触摸状态:

MotionEvent.ACTION_DOWN:按下

MotionEvent.ACTION_MOVE:移动

MotionEvent.ACTION_UP:放开

所以我们通常是通过switch进行分类处理的,switch(event.getAction ),然后每个case ~:处理对应事件



方法调用顺序解析:

由方法声明我们知道onTouchEvent返回的是一个boolean值,要么true,要么false

而这两个的不同之处就是,调用完onTouch()中的方法后是否再调用外部的方法


这里举个简单的例子:

我们为某个按钮设置了onTouch(),onClick(),onLongClick()三个方法;那么他们的调用顺序是怎么样的呢?


答:有以下两种情况:

①返回true:按下时调用ACTION_DOWN的方法,调用完后调用ACTION_MOVE方法,只要手指一直按着系统就会不断地响应这个

方法,原因是(android对触摸事件比较敏感,虽然我们的手指感觉是静止不动的,其实手指却在不停地微颤抖震动);当我们的手指离开

了屏幕,这个时候调用 MotionEvent.ACTION_UP方法,接着这个流程就完了


②返回false:和上面那个流程一样,但是离开屏幕后就会调用另外的2个方法了:

如果你是短按的话,那么会调用onClick()方法

如果你是长按得话,那么会调用onLongClick()方法;

然后才玩完



上面的这两种情况并不难理解

读者可以自己写代码验证一下,然后通过log.i()查看调用的顺序信息


最后给大家演示一下

调用OnTouchEvent() onMove方法的使用吧


MoveTo()方法使用实例:



这个用的比较多,例子还是旧的,在帧布局那一节就给出来了

这里简单地介绍下用法吧:

我们只需要通过参数event就可以获得当前点击的位置了

x = event.getX();   //获得点击的X坐标

y = event.getY();   //获得点击的Y坐标


详细的见代码吧:

MoveTo方法使用实例


原文:

点击打开链接

那个随手指移动的萌妹子就是了!




总结:

好吧,这一节的基于监听的事件处理机制就总结到这里吧

如果有什么遗漏的,或者错误,或者有其他意见的

欢迎指出,O(∩_∩)O谢谢



更新日志:

2014.2.23:  漏掉了一种使用方式:直接把事件绑定到标签上,已添加

更多相关文章

  1. Android深入学习之各种隐私权限判断和获取方法总结
  2. Android拷贝工程不覆盖原工程的配置方法
  3. Android设置View的点击次数的工具类
  4. Android(安卓)管理多个fragment(处理Activity被回收的情况)
  5. 如何访问android的asset目录和res目录下的文件
  6. J2me游戏如何快速移植到Android(安卓)(2)
  7. 关于 android app 返回键模拟 home键 功能的介绍_仿QQ返回键 又
  8. Android的多媒体技术――MediaPlayer实现音频与视频的播放
  9. Android热修复(一):底层替换、类加载原理总结 及 DexClassLoader类

随机推荐

  1. Android(安卓)Socket 聊天工具(一个服务端
  2. Android(安卓)音乐播放器的实现(一)自定义
  3. Android(安卓)Launcher研究(一)---------
  4. Android:让WebView支持元素,实现文件上传
  5. Android解决RecyclerView嵌套RecyclerVie
  6. Android(安卓)TV 焦点上下左右移动
  7. Android(安卓)为什么TextView文本有内容
  8. Android(安卓)Studio自带数据库SQLite的
  9. Android(安卓)仿qq聊天界面之一
  10. Android(安卓)Studio 使用Git创建本地分