一.简单的思路为:生产者+消费者模式来实现
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到请求队列中