Android Studio开发学习(十四)——事件处理机制

一、前提

事件处理机制也有很多类型,在这里将简介几种常用的处理机制

二、目标

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();

    }
}

四、总结

事件处理机制很常用,也有很多技巧,运用灵活,多加练习

原创文章 30 获赞 5 访问量 1896

猜你喜欢

转载自blog.csdn.net/qq_41890177/article/details/105798251