一、前提
事件处理机制也有很多类型,在这里将简介几种常用的处理机制
二、目标
1、基于监听的事件处理机制
2、基于回调的事件处理机制
3、Handler
三、内容
1、基于监听的事件处理机制
监听事件处理有很多种方式,这里将会简介五种关于点击事件的处理方式
(1)通过android:OnClick=""方式处理
此方法用于在xml文件中添加,首先先布局一个按钮
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.sunny.eventactivity.MainActivity">
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="click"
android:onClick="show"
/>
</RelativeLayout>
在MainActivity中添加
package com.example.sunny.eventactivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void show(View v){
switch (v.getId()){
case R.id.btn:
Toast.makeText(MainActivity.this,"click",Toast.LENGTH_SHORT).show();
break;
}
}
}
(2)内部类,在一个类的内部再写一个类,调用
package com.example.sunny.eventactivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.btn);
//内部类实现
button.setOnClickListener(new OnClick());
}
class OnClick implements View.OnClickListener{
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn:
Toast.makeText(MainActivity.this,"click",Toast.LENGTH_SHORT).show();
break;
}
}
}
}
(3)匿名内部类,使用的最常见的方法
package com.example.sunny.eventactivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.btn);
//匿名内部类
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"click",Toast.LENGTH_SHORT).show();
}
});
}
}
(4)通过事件源所在的类实现,通过接口实现点击事件监听器,重写其方法后调用
package com.example.sunny.eventactivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.btn);
//通过事件源所在的类实现
button.setOnClickListener(MainActivity.this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn:
Toast.makeText(MainActivity.this,"click",Toast.LENGTH_SHORT).show();
break;
}
}
}
(5)外部类,首先先新建一个java类,之后在MainActivity中调用(使用的不多)
package com.example.sunny.eventactivity;
import android.app.Activity;
import android.view.View;
import android.widget.Toast;
/**
* Created by Sunny on 2020/4/27.
*/
public class OnClickListener implements View.OnClickListener{
private Activity activity;
public OnClickListener(Activity activity){
this.activity=activity;
}
@Override
public void onClick(View v) {
Toast.makeText(activity,"click",Toast.LENGTH_SHORT).show();
}
}
package com.example.sunny.eventactivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity{
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.btn);
//通过外部类实现
button.setOnClickListener(new OnClickListener(MainActivity.this));
}
}
注:
如果给同一事件添加多个同种类型监听器,意思也就是说,如果给一个按钮添加多个点击事件监听器,系统只会执行设置的最后一个事件监听器,如果在一个代码中,针对一个按钮,你先通过内部类设置一个事件,在通过匿名内部类设置同样一个事件,则只会执行匿名内部类设置的事件,覆盖了之前内部类设置的事件
以上五种方法的中间三种较为常用,当然也要根据项目来定
2、基于回调的事件处理机制
也有很多,像是触摸,抬起,摁下,都是回调方法
首先重写一个java类继承AppCompatButton,添加构造方法,重写onTouchEvent()触摸事件方法,代码意思是,当手指摁下时控制台打印内容
package com.example.sunny.eventactivity;
import android.content.Context;
import android.support.v7.widget.AppCompatButton;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.Button;
/**
* Created by Sunny on 2020/4/27.
*/
public class MyButton extends AppCompatButton {
public MyButton(Context context) {
super(context);
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("MyButton","--OnTouchEvent--");
break;
}
return false;
}
}
在activity_main布局文件中在添加一个按钮,注意这个按钮,是通过之前java类重写后自身设置的按钮
<com.example.sunny.eventactivity.MyButton
android:id="@+id/mybutton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="my_button"
/>
在MainActivity中添加,在主函数中也有onTouchEvent()方法,我们将它重写,且按钮自身也有触摸的监听事件
package com.example.sunny.eventactivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import static com.example.sunny.eventactivity.R.id.mybutton;
public class MainActivity extends AppCompatActivity{
private MyButton myButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButton= (MyButton) findViewById(mybutton);
myButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("Listener","--OnTouchEvent--");
break;
}
return false;
}
});
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
Log.d("MainActivity","--OnTouchEvent--");
break;
}
return false;
}
}
android.util.Log常用的方法有以下5个:Log.v() Log.d() Log.i() Log.w() 以及 Log.e() ,这些方法都是用来调试时查看信息的,各有各的用处以及显示的颜色,这里不多叙述
运行后我们可以看见它先执行了监听器中的方法,之后执行了Button类的方法,最后执行了主函数中的方法,这个是有优先级的,优先执行监听器的方法,在执行回调,回调将从控件本身内部开始,向外逐渐扩散。如果想表示到某一层你不想继续让它回调时,可将return false改为true表示到这一步自行解决,不用向外继续扩散。
3、Handler消息处理
Handler作为一个消息处理机制很常用且很灵活,这里简单的介绍一下,以下的代码表示一个常用的消息处理,三秒后页面自动跳转的处理,postDelayed()方法表示将可运行的r添加到消息队列中,使其在指定的时间量过期后运行。runnable将在附加该处理程序的线程上运行。
package com.example.sunny.handler;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler=new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent=new Intent(MainActivity.this,Test.class);
startActivity(intent);
}
}, 3000);//3s后跳转
}
}
最常用的还是处理线程的问题,通过一个线程传递一个信息,再在Handler中读取信息,根据信息来做出相应的动作
package com.example.sunny.handler;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
Toast.makeText(MainActivity.this, "线程通信", Toast.LENGTH_SHORT).show();
break;
}
}
};
new Thread(){
@Override
public void run() {
super.run();
Message message=new Message();
message.what=1;
handler.sendMessage(message);
}
}.start();
}
}
四、总结
事件处理机制很常用,也有很多技巧,运用灵活,多加练习