android 实现一个按钮按下时总触发一个事件

2023-11-04

一.简单的思路为:生产者+消费者模式来实现

1.重写这个对象的触摸事件(对触摸事件与事件分发机制的同学不了解的可以查阅其他资料)

2.在MotionEvent.ACTION_DOWN:事件中启动一个线程,这个线程类似生产者,它不停的生产想要的事件

这里的事件为了调用的顺序,建议采用队列的方式来缓存,事件对象可任意

3.在MptionEvent.ACTION_UP:事件中取消这个线程,取消线程即停止这个线程,采用置中断标记来停止一个线程

5.从任务队列中取出任务进行执行,类似消费者,代码模式与生产者很类似,具体的思路可参看我的前几编文章,里面有很详细的生产者消费者模式多线程的运用


二.任务请求对象:

package com.example.baize.touchdelegate.producer;

import java.util.LinkedList;

/**
 * 事件对象
 * <p>
 * Created by lxb on 2017/3/31.
 */

public class EventRequest<T> {

    private LinkedList<T> requestQueue = new LinkedList<>();
    private int count;    // 任务队列请求数

    public EventRequest() {
        this.count = 0;
    }

    public synchronized void buildEvent(T request) throws InterruptedException {

        while (!requestQueue.isEmpty() && count >= requestQueue.size()) {
            wait();
        }
        System.out.println(Thread.currentThread().getName() + "正在产生" + request + "到请求队列中");
        requestQueue.addLast(request);
        count++;
        notifyAll();
    }

    public synchronized T sendEvent() throws InterruptedException {
        while (count <= 0) {
            wait();
        }
        T request = requestQueue.pop();
        count--;
        notifyAll();
        System.out.println(Thread.currentThread().getName() + "已经成功从请求队列中拿到" + request);
        return request;
    }
}

三.生产者线程:

package com.example.baize.touchdelegate.producer;

/**
 * 生产游戏手柄的按键事件,本线程通过打断与启动标志来停止线程
 * <p>
 * Created by lxb on 2017/3/31.
 */

public class ProduceEventThread<T> extends Thread {

    private EventRequest<T> eventRequest;

    private volatile boolean terminated = false; // 停止请求标志

    private T type;       //事件请求类型

    public ProduceEventThread(T type, EventRequest<T> eventRequest) {

        this.eventRequest = eventRequest;
        this.type = type;
    }

    public void run() {
        while (!terminated) {

            try {
                this.eventRequest.buildEvent(type);

            } catch (InterruptedException e) {
                terminated = true;
            }

        }
    }

    public void cancel(){
        terminated = true;
        interrupt();
    }

}
四.消费者线程:

package com.example.baize.touchdelegate.producer;

/**
 * 发送游戏手柄事件的线程,类似消费者
 *
 * Created by lxb on 2017/3/31.
 */

public class SendEventThread<T> extends Thread {


    private EventRequest<T> eventRequest;

    private volatile boolean terminated = false; // 停止请求标志

    private T type;       //事件请求类型

    public SendEventThread(T type, EventRequest<T> eventRequest) {

        this.eventRequest = eventRequest;
        this.type = type;
    }

    public void run() {
        while (!terminated) {

            try {
                this.eventRequest.sendEvent();
            } catch (InterruptedException e) {
                terminated = true;
            }

        }
    }

    public void cancel(){
        terminated = true;
        interrupt();
    }
}

五。整个触摸对象的触摸事件代理类:

package com.example.baize.touchdelegate;

import android.view.MotionEvent;
import android.view.View;

import com.example.baize.touchdelegate.producer.EventRequest;
import com.example.baize.touchdelegate.producer.ProduceEventThread;
import com.example.baize.touchdelegate.producer.SendEventThread;

/**
 * 游戏手柄按键不停的产生事件,由此类进行代理并采用生产者消费者模式实现
 * <p>
 * Created by lxb on 2017/3/31.
 */

public class TouchEventDelegate<T> implements View.OnTouchListener {

    private T type ;

    private ProduceEventThread<T> produceEventThread;

    private SendEventThread<T> sendEventThread;

    private EventRequest<T> eventRequest;


    public TouchEventDelegate(T type) {
        this.type = type;
        eventRequest = new EventRequest<>();

    }


    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                startThreads();

                break;

            case MotionEvent.ACTION_MOVE:

                break;

            case MotionEvent.ACTION_UP:

                stopAllThreads();

                break;

        }

        return true;
    }

    private void startThreads() {
        produceEventThread = new ProduceEventThread<>(type, eventRequest);
        sendEventThread = new SendEventThread<>(type, eventRequest);
        produceEventThread.start();
        sendEventThread.start();
    }

    private void stopAllThreads() {
        if (produceEventThread != null) {
            produceEventThread.cancel();
            produceEventThread = null;
        }

        if (sendEventThread != null) {
            sendEventThread.cancel();
            sendEventThread = null;
        }

    }
}


调用方式:

package com.example.baize.activity;

import android.content.res.Configuration;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.TouchDelegate;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

import com.example.baize.R;
import com.example.baize.touchdelegate.TouchEventDelegate;
import com.example.baize.utils.VibrateUtils;

/**
 * 游戏手柄
 * Created by lxb on 2017/3/31.
 */

public class GameCtrlActivity extends BaseActivity{

    private ImageView mBack;
    private ImageView mLeft;
    private ImageView mRight;
    private ImageView mUp;
    private ImageView mDown;

    private ImageView mFun1;
    private ImageView mFun2;
    private ImageView mFun3;
    private ImageView mFun4;
    private ImageView mFun5;

    private ImageView mX;
    private ImageView mY;
    private ImageView mA;
    private ImageView mB;

    private static final Integer leftTouch = 101;
    private static final Integer upTouch = 102;
    private static final Integer rightTouch = 103;
    private static final Integer downTouch = 104;
    private static final String xTouch = "X";
    private static final String yTouch = "Y";
    private static final String aTouch = "A";
    private static final String bTouch = "B";

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

    @Override
    protected void setStatusBar() {
    }


    private void initView(){
        EventClick click = new EventClick();

        mBack = getView(R.id.gc_back);
        mLeft = getView(R.id.gc_left);
        mRight = getView(R.id.gc_right);
        mUp = getView(R.id.gc_up);
        mDown = getView(R.id.gc_down);

        mFun1 = getView(R.id.gc_fun1);
        mFun2 = getView(R.id.gc_fun2);
        mFun3 = getView(R.id.gc_fun3);
        mFun4 = getView(R.id.gc_fun4);
        mFun5 = getView(R.id.gc_fun5);

        mX = getView(R.id.gc_x);
        mY = getView(R.id.gc_y);
        mA = getView(R.id.gc_a);
        mB = getView(R.id.gc_b);


        mBack.setOnClickListener(click);

        /*mLeft.setOnClickListener(click);
        mRight.setOnClickListener(click);
        mUp.setOnClickListener(click);
        mDown.setOnClickListener(click);*/

        mFun1.setOnClickListener(click);
        mFun2.setOnClickListener(click);
        mFun3.setOnClickListener(click);
        mFun4.setOnClickListener(click);
        mFun5.setOnClickListener(click);

       /* mX.setOnClickListener(click);
        mY.setOnClickListener(click);
        mA.setOnClickListener(click);
        mB.setOnClickListener(click);*/

        mLeft.setOnTouchListener(new TouchEventDelegate<>(leftTouch));
        mUp.setOnTouchListener(new TouchEventDelegate<>(upTouch));
        mRight.setOnTouchListener(new TouchEventDelegate<>(rightTouch));
        mDown.setOnTouchListener(new TouchEventDelegate<>(downTouch));

        mX.setOnTouchListener(new TouchEventDelegate<>(xTouch));
        mY.setOnTouchListener(new TouchEventDelegate<>(yTouch));
        mA.setOnTouchListener(new TouchEventDelegate<>(aTouch));
        mB.setOnTouchListener(new TouchEventDelegate<>(bTouch));




    }

    private class EventClick implements View.OnClickListener{
        @Override
        public void onClick(View v) {

            VibrateUtils.vSimple(GameCtrlActivity.this, 100);

            switch(v.getId()){

                case R.id.gc_back:
                    GameCtrlActivity.this.finish();
                    break;

                case R.id.gc_fun1:
                case R.id.gc_fun2:
                case R.id.gc_fun3:
                case R.id.gc_fun4:
                case R.id.gc_fun5:
                    Toast.makeText(GameCtrlActivity.this,"未定义",Toast.LENGTH_SHORT).show();
                    break;

            }
        }
    }



}

测试结果:

04-01 09:11:16.727 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.727 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.728 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.728 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.728 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.728 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.728 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.728 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.729 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.729 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.729 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.729 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.730 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.730 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.730 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.730 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.731 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.731 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.731 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.731 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.732 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.732 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.732 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.732 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.732 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.733 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.733 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中
04-01 09:11:16.733 20460-21434/com.example.baize I/System.out: Thread-6183已经成功从请求队列中拿到X
04-01 09:11:16.740 20460-21433/com.example.baize I/System.out: Thread-6182正在产生X到请求队列中





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android 实现一个按钮按下时总触发一个事件 的相关文章

随机推荐

  • Timing Modeling--时序模型

    The cell timing models are intended to provide accurate timing for various instances of the cell in the design environme
  • c++实现进制转换

    目录 进制的相关概念 十进制转非十进制 非十进制转十进制 二进制转八进制 八进制转二进制 二进制转十六进制 十六进制转二进制 八进制转十六进制 十六进制转八进制 进制的相关概念 1 数码 在数制中表示数制大小的符号 比如十进制的数码 0 1
  • 卡尔曼滤波学习笔记

    这篇文章参考博客 介绍 卡尔曼滤波的一个典型事例是从一组有限的 包含噪声的对物体位置的观察序列 可能有偏差 预测出物体的位置的坐标及速度 卡尔曼最初提出的滤波器形式现在一般称为简单卡尔曼滤波器 除此之外还有施密特扩展滤波器 信息滤波器以及很
  • chatgpt赋能python:用Python写C语言:提高效率和可读性

    用Python写C语言 提高效率和可读性 Python和C语言是两种不同的编程语言 但是它们各有优劣 Python具有易读易写的特点和适合快速开发的能力 而C语言则更适合执行速度快的任务 那么 有什么方法可以让我们在保持C语言的速度的同时
  • 我总结了程序员转行得最有出路5个方向

    先简单粗暴的回答您的问题 程序员转行做什么比较好 这个没有确切的答案 因人而异 下面我会结合身边几个大龄程序员的实际情况来说一说这个问题 会不会造成薪资的大幅下降 一开始肯定会的 毕竟隔行如隔山 我们刚开始从事软件开发工作不也就三四千块钱一
  • tomcat启动错误:Error running tomcat: Address localhost:1099 is already in use

    tomcat启动错误 Error running tomcat Address localhost 1099 is already in use 这是tomcat上一次启动后没有正常关闭或者遭遇异常导致的服务器某些线程没有完全关闭 这里就是
  • 2022跨年烟花代码(五)HTML5全屏烟花特效

    HTML5全屏烟花特效 html代码
  • 远程调试、无cuDnn、自定义模块无法导入问题记录

    说明 记录自己的错误 慢慢来 比较快 1 Pycharm远程调试出现错误 root miniconda3 bin python can t open file root autodl tmp mian py Errno 2 No such
  • java 中 热部署与卸载关系

    今天发现早年在大象笔记中写的一篇笔记 之前放在ijavaboy上的 现在它已经访问不了了 前几天又有同事在讨论这个问题 这里拿来分享一下 在web应用开发或者游戏服务器开发的过程中 我们时时刻刻都在使用热部署 热部署的目的很简单 就是为了节
  • abstract关键字(抽象类)【Java】

    目录 一 abstract关键字 1 1 abstract修饰类 抽象类 1 2 abstract 修饰方法 抽象方法 1 3 abstract使用的注意点 二 abstract 关键字的举例说明 一 abstract关键字 解释为抽象的
  • PC常用软件

    PotPlayer播放器 功能齐全 无广告 下载地址 Geek卸载软件 体积小 功能强 专职卸载 无广告 下载免费版 Internet Download Manager下载软件 可以接管浏览器下载 下载速度快 没迅雷那么麻烦 下载地址 7
  • CSS基础样式和排版文本段落

    一 CSS基础样式 1 字体属性 font family是字体属性 font family 后面可以直接打出来字体的样式 或者直接选择 font family Times Times New Roman 楷体 也可以用是为啥 如果浏览器认识
  • 什么是Hash?

    原文链接 https www cnblogs com ktao p 8714513 html 什么是Hash Hash中文翻译为散列 又成为 哈希 是一类函数的统称 其特点是定义域无限 值域有限 把任意长度的输入 又叫做预映射 pre im
  • vue——数字加逗号分隔

    带小数的数字三位一分隔 filters num val fix 2 gt if val 0 val Number val 字符串转为数字 目标数据为数字可不转 val val toFixed 2 保留两位小数并转为字符串 let int v
  • IE中CSS-filter滤镜小知识大全

    本文转载 并做了部分修改 原文链接https segmentfault com a 1190000002433305 前言 前段时间在做一个专题的时候用到了opacity不透明度属性 因为设计图上是半透明背景 白色文字 有时候我们很习惯的用
  • 走过路过的帅哥美女,进来了解一下异常吧!

    异常的概念 异常是程序在运行过程中所发生的意外事件 它中断指令的正常执行 在Object类下的Throwable 有两个重要的子类 Exception 异常 和 Error 错误 二者都是 Java 异常处理的重要子类 各自都包含大量子类
  • 间谍高度(上帝视角)之redis分布式锁

    间谍高度 上帝视角 和redis分布式锁 一 写作动机的初衷 1 1 分享与留下 二 分享 2 1 间谍高度 2 2感受 三 留下 3 1专业技术的思考 四 redis分布式锁的内容 4 1代码 抢锁代码 加锁代码 解锁代码 效果演示 4
  • windows上利用C++语言查询设备 (windows,vs2010,SetupDiEnumDeviceInfo)

    代码功能将windows设备遍历一次 然后将结果直接存放到map容器中 需要清楚其中一个设备的个数 直接通过map可以查询 include
  • 记录将代码文件上传到Github托管平台,简单快捷,容易操作

    第一步 下载GitHub Desktop到电脑 贴出爱心链接 一键直达 GitHub Desktop Simple collaboration from your desktop 第二步 安装到你想安装的地址 第三步 相信你已经注册过git
  • android 实现一个按钮按下时总触发一个事件

    一 简单的思路为 生产者 消费者模式来实现 1 重写这个对象的触摸事件 对触摸事件与事件分发机制的同学不了解的可以查阅其他资料 2 在MotionEvent ACTION DOWN 事件中启动一个线程 这个线程类似生产者 它不停的生产想要的