Android 事件机制 - 监听

Android UI 控件方面就告一段落了,还有一些其它的 UI 控件没讲,但大多都是大同小异,相信你学习了辣么多的,自己去学其它的应该没啥问题

本章节开始我们讲讲 Android 中的事件处理机制

事件处理机制

不管是桌面应用还是手机应用程序,面对最多的就是用户,经常需要处理的就是用户动作,也就是需要为用户动作提供响应,这种为用户动作提供响应的机制就是事件处理

比如,用户点击 没有账号 就要跳转到注册页面,点击 忘记密码 就要跳转到重置密码界面

Android 提供了两套事件处理机制

  1. 基于监听的事件处理

    这种事件处理方式就是给 Android UI 控件绑定特定的事件监听器

  2. 基于回调的事件处理

    这种事件处理方式就是重写 Android UI 控件的特定事件回调方法,或者重写 Activity 特定的回调方法

一般情况下我们推荐使用 基于回调的事件处理 ,但特殊情况下,只能使用 基于监听的事件处理

基于监听的事件处理机制

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

三者之间的关系和 基于监听的事件处理机制 的一般流程如下图

  1. 为某个事件源(组件)设置一个监听器,用于监听用户操作
  2. 用户的操作,触发了事件源的监听器
  3. 生成了对应的事件对象
  4. 将这个事件源对象作为参数传给事件监听器
  5. 事件监听器对事件对象进行判断,执行对应的事件处理器(对应事件的处理方法)

所以,我们也可以说

事件监听机制是一种委派式的事件处理机制,事件源(组件)事件处理委托给事件监听器 当事件源发生指定事件时,就通知指定事件监听器,执行相应的操作

五种不同的使用方式

我们可以使用五种方式给一个 UI 控件或 Activity 添加基于监听的事件

  1. 直接用匿名内部类 (推荐)
  2. 使用内部类
  3. 使用外部类
  4. 直接使用 Activity 作为事件监听器 (常用)
  5. 直接绑定到标签

我们以 单击按钮,Toast 提示信息 简单教程,简单编程 为例

  1. 创建一个 空的 Android 项目 cn.twle.android.EventListen

  2. 修改 activity_main.xml 添加一个按钮

    <?xml version="1.0" encoding="utf-8" ?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal" 
        android:orientation="vertical" >
    
        <Button
            android:layout_marginTop="16dp" 
            android:id="@+id/btn_ev"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="提示信息"/>
    
    </LinearLayout>
    

直接用匿名内部类

就是直接使用匿名类调用 setXxxListener() ,重写里面的方法

这是最常用的一种,通常是临时使用一次

修改 MainAcivity.java

package cn.twle.android.eventlisten;    

import android.os.Bundle;    
import android.view.View;    
import android.view.View.OnClickListener;    
import android.widget.Button;    
import android.widget.Toast;    
import android.support.v7.app.AppCompatActivity;   


public class MainActivity extends AppCompatActivity {    

    @Override    
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.activity_main);    

        Button btn_ev = (Button) findViewById(R.id.btn_ev);    

        btn_ev.setOnClickListener(new OnClickListener() {    

            //重写点击事件的处理方法 onClick()    
            @Override    
            public void onClick(View v) {    
                //显示 Toast 信息    
                Toast.makeText(getApplicationContext(), "简单教程,简单编程", Toast.LENGTH_SHORT).show();    
            }    
        });    
    }        
}

使用内部类

添加一个事件内部类,然后实例化一个对象传递给 setXxxListener() 作为对象

这种方法可以复用该事件类,而且可以直接访问外部类的所有界面组件

修改 MainAcivity.java

package cn.twle.android.eventlisten;    

import android.os.Bundle;    
import android.view.View;    
import android.widget.Button;    
import android.widget.Toast;    
import android.support.v7.app.AppCompatActivity;   


public class MainActivity extends AppCompatActivity {    

    @Override    
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.activity_main);    

        Button btn_ev = (Button) findViewById(R.id.btn_ev);    

        //直接 new 一个内部类对象作为参数    
        btn_ev.setOnClickListener(new BtnClickListener());    
    }


    //定义一个内部类,实现 View.OnClickListener 接口,并重写 onClick() 方法    
    class BtnClickListener implements View.OnClickListener    
    {    
        @Override    
        public void onClick(View v) {    
            Toast.makeText(getApplicationContext(), "简单教程,简单编程", Toast.LENGTH_SHORT).show();   
        }    
    }    
}

使用外部类

另外创建一个 Java 文件实现事件类

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

最直接的影响就是代码不够简洁

MainActivity.java 同一目录下新建文件 MsClick.java

package cn.twle.android.eventlisten;    

import android.content.Context;
import android.view.View;    
import android.view.View.OnClickListener;     
import android.widget.Toast;

public class MsClick implements OnClickListener {    

    private String msg;
    private Context mContext;  

    //把要提示的文本作为参数传入    
    public MsClick(Context mContext,String msg)    
    {    
        this.msg = msg; 
        this.mContext = mContext;   
    }    
    @Override    
    public void onClick(View v) {    

        // 提示传入的信息   
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();    
    }    
}

然后修改 MainActivity.java

package cn.twle.android.eventlisten;    

import android.os.Bundle;    
import android.view.View;    
import android.view.View.OnClickListener;    
import android.widget.Button;    
import android.widget.Toast;    
import android.support.v7.app.AppCompatActivity;   


public class MainActivity extends AppCompatActivity {    

    @Override    
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.activity_main);    

        Button btn_ev =  (Button) findViewById(R.id.btn_ev);    

        //直接 new 一个外部类,并把 "简单教程,简单编程"  作为参数传入    
        btn_ev.setOnClickListener(new MsClick(MainActivity.this,"简单教程,简单编程"));    
    }         
}

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

Activity 类实现 XxxListener 事件监听接口,然后在 Activity 中定义重写对应的事件处理器方法,最后调用 setXxx.Listener(this)

比如,Actitity 实现了 OnClickListener 接口,重写 onClick(view) 方法在为某些 UI 控件添加该事件监听对象

修改 MainAcivity.java

package cn.twle.android.eventlisten;    

import android.os.Bundle;    
import android.view.View;    
import android.view.View.OnClickListener;    
import android.widget.Button;    
import android.widget.Toast;    
import android.support.v7.app.AppCompatActivity;   



//让 Activity 方法实现 OnClickListener 接口 
public class MainActivity extends AppCompatActivity implements View.OnClickListener {    

    @Override    
    protected void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.activity_main);    

        Button btn_ev = (Button) findViewById(R.id.btn_ev);    

        //直接写个 this    
        btn_ev.setOnClickListener(this);    
    }    

    //重写接口中的抽象方法    

    @Override    
    public void onClick(View v) {    
        Toast.makeText(getApplicationContext(), "简单教程,简单编程", Toast.LENGTH_SHORT).show();         
    }         
}

直接绑定到标签

就是直接在 xml 布局文件中对应的 Activity 中定义一个事件处理方法

public void msClick(View source)

source 对应事件源( UI 控件类型),接着布局文件中对应要触发事件的 UI 控件设置一个属性

android:onclick = "msClick

范例

  1. 修改 MainAcivity.java

    package cn.twle.android.eventlisten;
    
    import android.os.Bundle;    
    import android.view.View;    
    import android.view.View.OnClickListener;    
    import android.widget.Button;    
    import android.widget.Toast;    
    import android.support.v7.app.AppCompatActivity;
    
    // Activity 方法实现 OnClickListener 接口 
    public class MainActivity extends AppCompatActivity {
    
        @Override    
        protected void onCreate(Bundle savedInstanceState) {    
            super.onCreate(savedInstanceState);    
            setContentView(R.layout.activity_main);     
        }    
        //自定义一个方法,传入一个 view 组件作为参数    
        public void msClick(View source)    
        {    
            Toast.makeText(getApplicationContext(), "简单教程,简单编程", Toast.LENGTH_SHORT).show();    
        }    
    }
    
  2. 修改 activity_main.xmlButton 添加 android:onclick 属性

    <?xml version="1.0" encoding="utf-8" ?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_horizontal" 
        android:orientation="vertical" >
    
        <Button
            android:layout_marginTop="16dp" 
            android:id="@+id/btn_ev"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="msClick"
            android:text="提示信息"/>
    
    </LinearLayout>
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.