Presentation is loading. Please wait.

Presentation is loading. Please wait.

第四章 Android事件处理机制 QQ群:287966120 Q Q号: 2227351322 倚动软件工厂实验室.

Similar presentations


Presentation on theme: "第四章 Android事件处理机制 QQ群:287966120 Q Q号: 2227351322 倚动软件工厂实验室."— Presentation transcript:

1 第四章 Android事件处理机制 QQ群: Q Q号: 倚动软件工厂实验室

2 4.1主要内容 基于监听的事件处理 基于回调的事件处理 异步任务处理 事件处理 直接绑定到标签 Handler消息处理机制

3 4.1 结构导图

4 4.1.1Android的事件处理机制 基于监听的事件处理 基于回调的事件处理 直接绑定到标签
通常做法是重写Android组件特定的回调方法,Android为绝大部分界面组件都提供了事件响应的回调方法,我们只需重写它们即可,由系统根据具体情景自动调用。 直接绑定到标签 主要做法是在界面布局文件中为指定标签设置事件属性,属性值是一个方法的方法名,然后再在Activity中定义该方法,编写具体的事件处理代码。

5 4.1.1基于监听的事件处理 基于监听的事件处理模型中,主要涉及到三类对象:
EventSource(事件源):产生事件的组件即事件发生的场所,如按钮、菜单等; Event(事件):具体某一操作的详细描述,事件封装了操作的相关信息,如果想获得事件源上所发生事件的相关信息,可通过Event对象来取得,例如按键事件按下的是哪个键、触摸事件发生的位置等; EventListener(事件监听器):负责监听用户在事件源上的操作,并对用户的各种操作做出相应的响应,事件监听器中可包含多个事件处理器,一个事件处理器实际上就是一个事件处理方法。

6 4.1.1基于监听的事件处理 这三类对象如何协同工作呢? 基于监听的事件处理是一种委托式事件处理;
普通组件(事件源)将整个事件处理委托给特定的对象(事件监听器); 当该事件源发生指定的事情时,系统自动生成事件对象,并通知所委托的事件监听器,由事件监听器相应的事件处理器来处理这个事件。

7 4.1.1基于监听的事件处理 基于监听的事件处理模型

8 4.1.1基于监听的事件处理 对委托式事件处理的理解: 委托式事件处理就如同生活中我们每个人的能力都有
限,当碰到一些自己处理不了的事情时,就委托给某个机 构或公司来处理。 首先,你需要把你所遇到的事情和要求向对方描述清 楚,这样,他人才能更好地解决问题; 其次,该机构不止处理你一个人的事,会选派具体的 员工来处理这件事。 其中,我们自己就是事件源,你遇到的事情就是事件, 该机构就是事件监听器,具体解决事情的员工就是事件处 理器。

9 4.1.1基于监听的事件处理 基于监听的事件处理模型的编程步骤: Step1:获取普通界面控件(事件源),即被监听的对象;
Step2:实现事件监听器类,该监听器类是一个特殊的 Java类,必须实现一个XxxListerner接口; Step3:调用事件源的setXxxListener方法将事件监听器对 象注册给普通组件(事件源)。

10 4.1.1基于监听的事件处理 实现事件监听器的四种形式: 内部类形式:将事件监听器类定义为当前类的内部类;
外部类形式:将事件监听器类定义成一个外部类; 类自身作为事件监听器类:让Activity本身实现监听器接口,并实现事件处理方法; 匿名内部类形式:使用匿名内部类创建事件监听器对象。

11 4.1.1基于监听的事件处理 简易文本编辑器实例

12 4.1.1基于监听的事件处理 ①先实现程序界面,代码示例TextEditor01
<LinearLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="测试文字,测试文字" /> →总体垂直线性布局 →为文本框添加ID,便于查找 →文本框宽度填充父容器 →文本框高度填充父容器 →文本内容水平居中 →设定文本显示内容

13 4.1.1基于监听的事件处理 <LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:orientation="horizontal" > <TextView android:text="颜色" /> <Button android:text="红色" /> →左边距为10dp →水平线性布局 →文本框宽度为内容包裹 →文本框高度为内容包裹 →在string 文件中设置颜色 →为按钮添加id →按钮宽度为内容包裹 →按钮高度为内容包裹 →在string 文件中设置颜色

14 4.1.1基于监听的事件处理 <Button android:id="@+id/green"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="绿色" /> android:text="蓝色" /> </LinearLayout> →为按钮添加id →按钮宽度为内容包裹 →按钮高度为内容包裹 →在String中设置颜色 →为按钮添加id →按钮宽度为内容包裹 →按钮高度为内容包裹 →在String中设置颜色

15 4.1.1基于监听的事件处理 <LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:orientation="horizontal" > <TextView android:text="大小" /> <Button android:text="增大" /> →线性布局宽度为内容包裹 →线性布局高度为内容包裹 →左边距为10dp →文本框宽度为内容包裹 →文本框高度为内容包裹 →在String中设置文本 →为按钮设置ID →按钮宽度为内容包裹 →按钮高度为内容包裹 →在String中设置文本

16 4.1.1基于监听的事件处理 <Button android:id="@+id/smaller"
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="缩小" /> </LinearLayout> <LinearLayout android:layout_marginLeft="10dp" android:orientation="horizontal" > <TextView android:text="样式"/> →为按钮设置ID属性 →按钮宽度为内容包裹 →按钮高度为内容包裹 →在string中设置文本 →按钮宽度为内容包裹 →按钮高度为内容包裹 →左边距为10dp →文本框宽度为内容包裹 →文本框高度为内容包裹 →在string中设置文本

17 4.1.1基于监听的事件处理 <Button android:id="@+id/italic "
android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="倾斜" /> " android:text="加粗" /> android:text="默认" /> </LinearLayout> →为按钮设置ID属性 →按钮宽度为内容包裹 →按钮高度为内容包裹 →在string中设置文本 →为按钮设置ID属性 →按钮宽度为内容包裹 →按钮高度为内容包裹 →在string中设置文本 →为按钮设置ID属性 →按钮宽度为内容包裹 →按钮高度为内容包裹 →在string中设置文本

18 4.1.1基于监听的事件处理 <LinearLayout android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:orientation="horizontal" > <TextView android:text="内容"/> <EditText android:layout_width="200dp" android:layout_height="wrap_content" /> </LinearLayout> →左边距为10dp →文本框宽度为内容包裹 →文本框高度为内容包裹 →在string中设置文本 →为输入框设置ID属性 →输入框宽度为内容包裹 →输入框高度为内容包裹

19 4.1.1基于监听的事件处理 ②为“红色,绿色,蓝色”三个按钮添加事件监听器,采用内部类的形式实现,代码示例TextEditor01
public class MainActivity extends Activity { private Button red, green, blue; private TextView test; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); red = (Button) findViewById(R.id.red); green = (Button) findViewById(R.id.green); blue = (Button) findViewById(R.id.blue); test = (TextView) findViewById(R.id.test); MyListener myColorListener = new MyListener(); red.setOnClickListener(myColorListener); green.setOnClickListener(myColorListener); blue.setOnClickListener(myColorListener); } →根据ID获取组件 →注册监听器 →注册监听器 →注册监听器

20 4.1.1基于监听的事件处理 private class MyListener implements OnClickListener {
public void onClick(View v) { switch (v.getId()) { case R.id.red: test.setTextColor(Color.RED); break; case R.id.blue: test.setTextColor(Color.BLUE); case R.id.green: test.setTextColor(Color.GREEN); default:break; } →实现监听器的内部类 →判断事件源 →将字体设置为红色 →将字体设置为蓝色 →将字体设置为绿色

21 4.1.1基于监听的事件处理 使用内部类有两个优势: 使用内部类可以在当前类中复用该监听器类,即多个事件源可以注册同一个监听器;
使用内部类可以自由访问外部类的所有界面控件,内部类实质上是外部类的成员。 内部类形式比较适合于有多个事件源同时注册同一事件监听器的情形。

22 4.1.1基于监听的事件处理 ③为“增大”和“缩小”按钮添加事件监听器,采用外部类的形式实现,代码示例TextEditor02
public class MainActivity extends Activity { private Button bigger, smaller; private TextView test; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bigger = (Button) findViewById(R.id.bigger); smaller = (Button) findViewById(R.id.smaller); test = (TextView) findViewById(R.id.test); SizeListener outLister = new SizeListener(test); bigger.setOnClickListener(outLister); smaller.setOnClickListener(outLister); } →根据ID获取组件 →创建监听器 →注册监听器 →注册监听器

23 4.1.1基于监听的事件处理 public class SizeListener implements OnClickListener {
private TextView tv; public SizeListener(TextView tv) {this.tv = tv; } public void onClick(View v) { float f=tv.getTextSize(); switch (v.getId()) { case R.id.bigger: f=f+2; break; case R.id.smaller: f=f-2; break; default:break; } if(f>=72){ f=72;} if(f<=8){ f=8; } tv.setTextSize(f); →实现监听器的外部类 →初始化需要传入的控件 →获取当前的字体大小 →判断是增大还是缩小 →字体每次增大2 →字体每次减小2 →判断字体是否大于72 →判断字体是否小于8 →设置字体大小

24 4.1.1基于监听的事件处理 那么如何在该类中获取到需要改变的控件呢? 在SizeListener的构造方法里传入参数的方式。
SizeListener 是一个外部类,该类实现了OnClickListener接口,可以处理单击事件,但外部类是无法获取到Activity里面的界面控件,也就不能对控件进行设置和更新。 那么如何在该类中获取到需要改变的控件呢? 在SizeListener的构造方法里传入参数的方式。

25 4.1.1基于监听的事件处理 外部类形式较少见的原因: 事件监听器通常属于特定的GUI(图形用户界面),定义成外部类不利于提高程序的内聚性;

26 4.1.1基于监听的事件处理 ④为“加粗、倾斜、默认”三个按钮添加事件处理器,采用Activity类本身继承OnClickListener实现,代码示例TextEditor03。 public class MainActivity extends Activity implements OnClickListener { private Button italic, bold, normal; private TextView test; private int flag=0; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); italic = (Button) findViewById(R.id.italic); bold = (Button) findViewById(R.id.bold); normal = (Button) findViewById(R.id.moren); test = (TextView) findViewById(R.id.test); italic.setOnClickListener(this); bold.setOnClickListener(this); normal.setOnClickListener(this); }

27 4.1.1基于监听的事件处理 flag=0表示默认,flag=1表示倾斜, flag=2表示加粗,flag=3表示既倾斜又加粗
public void onClick(View v) { switch (v.getId()) { case R.id.italic: if(flag==2||flag==3){ test.setTypeface(Typeface.MONOSPACE,Typeface.BOLD_ITALIC); flag=3; }else{test.setTypeface(Typeface.MONOSPACE,Typeface.ITALIC); flag=1;} break; case R.id.bold: if(flag==1||flag==3){ }else{test.setTypeface(Typeface.DEFAULT_BOLD,Typeface.BOLD); flag=2;} case R.id.moren: test.setTypeface(Typeface.MONOSPACE,Typeface.NORMAL); flag=0;break; default:break;} } →判断哪个按钮被单击了 flag=0表示默认,flag=1表示倾斜, flag=2表示加粗,flag=3表示既倾斜又加粗 →单击倾斜按钮 →单击加粗按钮 →单击默认按钮

28 4.1.1基于监听的事件处理 Activity类本身作为事件监听器,就如同生活中,我们自己刚好能够处理某一件事,不需要委托给他人处理,可以直接在Activity类中定义事件处理器方法,这种形式非常简洁。 不推荐使用的原因: 可能造成程序结构混乱,Activity的主要职责应该是完成界面初始化工作,但此时还需包含事件处理器方法,从而引起混乱; 如果Activity界面类需要实现监听器接口,给人感觉比较怪异。

29 思考:在上面的程序中,单击事件监听器的具体事件处理器中,并没有接收到事件参数,即我们并没有发现事件的“踪迹”,这是为什么呢?
4.1.1基于监听的事件处理 思考:在上面的程序中,单击事件监听器的具体事件处理器中,并没有接收到事件参数,即我们并没有发现事件的“踪迹”,这是为什么呢? 因为Android对事件监听模型做了进一步的简化:如果事件源触发的事件足够简单、事件里封装的信息比较有限,那无须封装事件对象。而对于见键盘事件、触摸事件等,程序需要获取事件发生的详细信息,如键盘中的哪个键触发的事件,触摸所发生的位置等,对于这种包含更多信息的事件,Android会将事件信息封装成XXXEvent对象,然后传递给事件监听器。

30 4.1.1基于监听的事件处理 ⑤为文本编辑框添加输入事件监听器,采用匿名内部类的形式来实现,代码示例TextEditor04
public class MainActivity extends Activity { private TextView test; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); test = (TextView) findViewById(R.id.test); final EditText content=(EditText)findViewById(R.id.content); content.setOnEditorActionListener(new OnEditorActionListener() { public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { test.setText(content.getText().toString()); return true; } }); content应定义为MainActivity的成员变量或者为final修饰的局部变量,否则无法在匿名内部类中访问该变量。

31 4.1.1基于监听的事件处理 匿名内部类中访问局部成员变量时,该成员变量必须是final修饰的,而对于成员变量则没有这个要求。
大部分时候,事件处理器都没有什么复用价值(可复用代码通常都被抽象成了业务逻辑方法),因此大部分事件监听器只是临时使用一次,所以使用匿名内部类形式的事件监听器更合适。实际上,这种形式也是目前使用最广泛的事件监听器形式。

32 基于监听的事件处理 常见事件监听器接口及其处理方法: 事件 接口 处理方法 描述 单击事件 View.OnClickListener
abstract void onClick(View v) 单击组件时触发 View.OnLongClickListener abstract boolean onLongClick (View v) 长按组件时触发 键盘事件 View.OnKeyListener abstract boolean onKey (View v, int keyCode, KeyEvent event) 处理键盘事件 焦点事件 View.OnFocusChangeListener abstract void onFocusChange (View v, boolean hasFocus) 当焦点发生改变时触发 触摸事件 View.OnTouchListener abstract boolean onTouch (View v, MotionEvent event) 产生触摸事件

33 4.1.1基于监听的事件处理 View类的常见事件监听器注册方法: 方法 描述 注册单击事件 注册长按事件 注册键盘事件 注册焦点改变事件
void setOnClickListener (View.OnClickListener l) 注册单击事件 void setOnLongClickListener (View.OnLongClickListener l) 注册长按事件 void setOnKeyListener(View.OnKeyListener l) 注册键盘事件 void setOnFocusChangeListener (View.OnFocusChangeListener l) 注册焦点改变事件 void setOnTouchListener (View.OnTouchListener l) 注册触摸事件 void setOnCreateContextMenuListener( View.OnCreateContextMenuListener l) 注册上下文菜单事件

34 休息一下吧


Download ppt "第四章 Android事件处理机制 QQ群:287966120 Q Q号: 2227351322 倚动软件工厂实验室."

Similar presentations


Ads by Google