我发布的同一个应用程序再次出现错误。请再次帮助我。非常感谢
这是错误:
07-30 16:57:08.613: E/AndroidRuntime(655): java.lang.ArrayIndexOutOfBoundsException: length=12; index=-1
07-30 16:57:08.613: E/AndroidRuntime(655): at java.util.ArrayList.get(ArrayList.java:306)
07-30 16:57:08.613: E/AndroidRuntime(655): at sample.app.touchsample.TouchsampleActivity.getTouchedViews(TouchsampleActivity.java:365)
07-30 16:57:08.613: E/AndroidRuntime(655): at sample.app.touchsample.TouchsampleActivity.dealEvent(TouchsampleActivity.java:78)
07-30 16:57:08.613: E/AndroidRuntime(655): at sample.app.touchsample.TouchsampleActivity.onTouch(TouchsampleActivity.java:294)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.View.dispatchTouchEvent(View.java:7122)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2170)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1905)
07-30 16:57:08.613: E/AndroidRuntime(655): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1925)
07-30 16:57:08.613: E/AndroidRuntime(655): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1379)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.app.Activity.dispatchTouchEvent(Activity.java:2396)
07-30 16:57:08.613: E/AndroidRuntime(655): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1873)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.View.dispatchPointerEvent(View.java:7307)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3172)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3117)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4153)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4132)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4224)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.os.MessageQueue.nativePollOnce(Native Method)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.os.MessageQueue.next(MessageQueue.java:125)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.os.Looper.loop(Looper.java:124)
07-30 16:57:08.613: E/AndroidRuntime(655): at android.app.ActivityThread.main(ActivityThread.java:4745)
07-30 16:57:08.613: E/AndroidRuntime(655): at java.lang.reflect.Method.invokeNative(Native Method)
07-30 16:57:08.613: E/AndroidRuntime(655): at java.lang.reflect.Method.invoke(Method.java:511)
07-30 16:57:08.613: E/AndroidRuntime(655): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
07-30 16:57:08.613: E/AndroidRuntime(655): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
07-30 16:57:08.613: E/AndroidRuntime(655): at dalvik.system.NativeStart.main(Native Method)
这是 MainActivity 的代码:
package sample.app.touchsample;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Context;
import android.graphics.Path;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
//import sample.app.touchsample.TouchsampleActivity.secondDrum.thirdDrum;
import android.widget.LinearLayout;
public class TouchsampleActivity extends Activity implements OnTouchListener
{
MediaPlayer mp;
SoundPool fx;
HashMap <Integer, Integer> fxMap;
int sfxId=1;
int sfxId2=2;
int sfxId3=3;
int sfxId4=4;
private Path path = new Path();
private View parent;
private final ArrayList[] recentTouchedViewsIndex = new ArrayList[12];
private final ArrayList[] downTouchedViewsIndex = new ArrayList[12];
private final ArrayList<View> moveOutsideEnabledViews = new ArrayList<View>();
private final ArrayList<View> multiTouchViews = new ArrayList<View>();
private int mTouchSlop = 24;
private static final String TAG = "Touch";
//private ImageView imageView1, imageView2 ;
public void addMoveOutsideEnabledViews(final View view) {
moveOutsideEnabledViews.add(view);
}
private void dealEvent(final int actionPointerIndex,
final MotionEvent event, final View eventView,
final int actionResolved) {
int rawX, rawY;
final int location[] = { 0, 0 };
eventView.getLocationOnScreen(location);
// Log.v("tag", location + "");
rawX = (int) event.getX(actionPointerIndex) + location[0];
rawY = (int) event.getY(actionPointerIndex) + location[1];
final int actionPointerID = event.getPointerId(actionPointerIndex);
ArrayList<View> hoverViews = getTouchedViews(rawX, rawY);
if (actionResolved == MotionEvent.ACTION_DOWN) {
downTouchedViewsIndex[actionPointerID] = (ArrayList<View>) hoverViews
.clone();
}
// deletes all views which where not clicked on ActionDown
if (downTouchedViewsIndex[actionPointerID] != null) {
final ArrayList<View> tempViews = (ArrayList<View>) hoverViews
.clone();
tempViews.removeAll(downTouchedViewsIndex[actionPointerID]);
hoverViews.removeAll(tempViews);
}
if (recentTouchedViewsIndex[actionPointerID] != null) {
final ArrayList<View> recentTouchedViews = recentTouchedViewsIndex[actionPointerID];
final ArrayList<View> shouldTouchViews = (ArrayList<View>) hoverViews
.clone();
if (!shouldTouchViews.containsAll(recentTouchedViews)) {
shouldTouchViews.removeAll(recentTouchedViews);
shouldTouchViews.addAll(recentTouchedViews);
final ArrayList<View> outsideTouchedViews = (ArrayList<View>) shouldTouchViews
.clone();
outsideTouchedViews.removeAll(hoverViews);
}
recentTouchedViewsIndex[actionPointerID] = hoverViews;
hoverViews = shouldTouchViews;
} else {
recentTouchedViewsIndex[actionPointerID] = hoverViews;
}
if (actionResolved == MotionEvent.ACTION_UP) {
recentTouchedViewsIndex[actionPointerID] = null;
downTouchedViewsIndex[actionPointerID] = null;
}
dumpEvent(event);
for (final View view : hoverViews) {
int x, y;
view.getLocationOnScreen(location);
x = rawX - location[0];
y = rawY - location[1];
// View does not recognize that the Pointer is
// outside if the Pointer is not far away (>mTouchSlop)
if (recentTouchedViewsIndex[actionPointerID] != null) {
if (pointInView(x, y, mTouchSlop, view.getWidth(),
view.getHeight())) {
// Log.v("tag", "added because < mTouchSlop");
if (!recentTouchedViewsIndex[actionPointerID]
.contains(view)) {
recentTouchedViewsIndex[actionPointerID].add(view);
}
} else if (moveOutsideEnabledViews.contains(view)) {
Log.v("tag", "outside but gets event");
recentTouchedViewsIndex[actionPointerID].add(view);
}
}
final MotionEvent me = MotionEvent.obtain(event.getDownTime(),
event.getEventTime(), actionResolved, x, y,
event.getPressure(actionPointerIndex),
event.getPressure(actionPointerIndex),
event.getMetaState(), event.getXPrecision(),
event.getYPrecision(), event.getDeviceId(),
event.getEdgeFlags());
me.setLocation(x, y);
if (!me.equals(event)) {
// deals the Event
view.onTouchEvent(me);
}
// debug
if (actionResolved == MotionEvent.ACTION_MOVE) {
Log.v("tag",
"#" + actionPointerIndex + " Rawx:" + rawX + " rawy:"
+ rawY + " x:" + x + " y:" + y + " "
+ view.toString());
}
}
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu)
// {
// getMenuInflater().inflate(R.menu.touchsample, menu);
// return true;
// }
public class secondDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos2 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume2 = bongos2.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume2 = bongos2.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftvolume2 = curVolume2/maxVolume2;
float rightVolume2 = curVolume2/maxVolume2;
int priority2 = 1;
int no_loop2 = 0;
float normal_playback_rate2=1.0f;
fx.play(sfxId2, leftvolume2, rightVolume2, priority2, no_loop2, normal_playback_rate2);
return false;
}
}
public class thirdDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos3 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos3.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos3.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 2.0f;
fx.play(sfxId3, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
//return false;
}
}
public class forthDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos4 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos4.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos4.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 2.0f;
fx.play(sfxId4, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
//return false;
}
}
public boolean onTouch(View view, MotionEvent event)
{
dumpEvent(event);
AudioManager bongos = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 1.0f;
fx.play(sfxId, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
//return false;
//index of the pointer which starts this Event
final int actionPointerIndex = event.getActionIndex();
// resolve the action as a basic type (up, down or move)
int actionResolved = event.getAction() & MotionEvent.ACTION_MASK;
if (actionResolved < 7 && actionResolved > 4) {
actionResolved = actionResolved - 5;
}
if (actionResolved == MotionEvent.ACTION_DOWN) {
for (int ptrIndex = 0; ptrIndex < event.getPointerCount(); ptrIndex++) {
// only one event for all move events.
dealEvent(ptrIndex, event, view, actionResolved);
Log.v("tag", "move" + ptrIndex);
}
} else {
dealEvent(actionPointerIndex, event, view, actionResolved);
}
return false;
}
private void dumpEvent(MotionEvent event)
{
final String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
final StringBuilder sb = new StringBuilder();
final int action = event.getAction();
final int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if(actionCode == MotionEvent.ACTION_POINTER_DOWN)
{
sb.append("(pid " ).append(action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")" );
}
sb.append("[");
for (int i = 0; i <event.getPointerCount(); i++)
{
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if(i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
Log.d(TAG, sb.toString());
}
private ArrayList<View> getChildViews(final View view) {
final ArrayList<View> views = new ArrayList<View>();
if (view instanceof ViewGroup) {
final ViewGroup v = ((ViewGroup) view);
if (v.getChildCount() > 0) {
for (int i = 0; i < v.getChildCount(); i++) {
views.add(v.getChildAt(i));
}
}
}
return views;
}
private ArrayList<View> getTouchedViews(final int x, final int y) {
View lastTouchedView = null;
final ArrayList<View> touchedViews = new ArrayList<View>();
final ArrayList<View> possibleViews = new ArrayList<View>();
if (parent instanceof ViewGroup) {
possibleViews.add(parent);
for (int i = 0; i < possibleViews.size(); i--) {
final View view = possibleViews.get(i);
final int location[] = { 0, 0 };
view.getLocationOnScreen(location);
if (((view.getHeight() + location[1] >= y)
& (view.getWidth() + location[0] >= x)
& (view.getLeft() <= x) & (view.getTop() <= y))
|| view instanceof FrameLayout) {
if (this.multiTouchViews.contains(view)){
lastTouchedView = view;
}
possibleViews.addAll(getChildViews(view));
}
}
//ArrayList<View> touchedViews = new ArrayList<View>();
if (lastTouchedView != null){
touchedViews.add(lastTouchedView);
}
return touchedViews;
}
return possibleViews;
}
//@Override
//public void onCreate(final Bundle instance) {
// super.onCreate(instance);
//public boolean onTouch(final View v, final MotionEvent event) {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
setContentView(R.layout.touchsample);
fx=new SoundPool(1100, AudioManager.STREAM_MUSIC, 1100);
fxMap=new HashMap<Integer, Integer>();
fxMap.put(sfxId, fx.load(this, R.raw.bongo_left, 1));
fxMap.put(sfxId2, fx.load(this, R.raw.bongo_right, 1));
fxMap.put(sfxId3, fx.load(this, R.raw.bongo_left, 1));
fxMap.put(sfxId4, fx.load(this, R.raw.bongo_right, 1));
parent = findViewById(android.R.id.content).getRootView();
parent.setOnTouchListener(this);
mTouchSlop = ViewConfiguration.get(getApplicationContext())
.getScaledTouchSlop();
}
private boolean pointInView(final float localX, final float localY,
final float slop, final float width, final float height) {
return localX >= -slop && localY >= -slop && localX < ((width) + slop)
&& localY < ((height) + slop);
}
}
和扩展:
package sample.app.touchsample;
import java.util.HashMap;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
public class Multitouch extends TouchsampleActivity{
private ImageView imageview1, imageview2, imageview3, imageview4;
MediaPlayer mp;
SoundPool fx;
HashMap <Integer, Integer> fxMap;
int sfxId=1;
int sfxId2=2;
int sfxId3=3;
int sfxId4=4;
@Override
public void onCreate(final Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.touchsample);
fx=new SoundPool(1100, AudioManager.STREAM_MUSIC, 1100);
fxMap=new HashMap<Integer, Integer>();
fxMap.put(sfxId, fx.load(this, R.raw.bongo_left, 1));
fxMap.put(sfxId2, fx.load(this, R.raw.bongo_right, 1));
fxMap.put(sfxId3, fx.load(this, R.raw.bongo_left, 1));
fxMap.put(sfxId4, fx.load(this, R.raw.bongo_right, 1));
ImageView view = (ImageView) findViewById(R.id.imageView1);
view.setOnTouchListener(this);
ImageView view2 = (ImageView) findViewById(R.id.imageView2);
view2.setOnTouchListener(new secondDrum());
ImageView view3 = (ImageView) findViewById(R.id.imageView3);
view3.setOnTouchListener(new thirdDrum());
ImageView view4 = (ImageView) findViewById(R.id.imageView4);
view4.setOnTouchListener(new forthDrum());
}
public boolean onTouch(View v, MotionEvent event)
{
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
//dumpEvent(event);
AudioManager bongos = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 1.0f;
fx.play(sfxId, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
case MotionEvent.ACTION_UP:
break;
}
class secondDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
//dumpEvent(event);
AudioManager bongos2 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume2 = bongos2.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume2 = bongos2.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftvolume2 = curVolume2/maxVolume2;
float rightVolume2 = curVolume2/maxVolume2;
int priority2 = 1;
int no_loop2 = 0;
float normal_playback_rate2=1.0f;
fx.play(sfxId2, leftvolume2, rightVolume2, priority2, no_loop2, normal_playback_rate2);
return false;
case MotionEvent.ACTION_UP:
break;
}
class thirdDrum implements OnTouchListener
{
public boolean onTouch(View view, MotionEvent event)
{
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
//dumpEvent(event);
AudioManager bongos3 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos3.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos3.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 2.0f;
fx.play(sfxId3, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
case MotionEvent.ACTION_UP:
break;
}
class forthDrum implements OnTouchListener
{
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
AudioManager bongos4 = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
float curVolume = bongos4.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = bongos4.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float leftVolume = curVolume/maxVolume;
float rightVolume = curVolume/maxVolume;
int priority = 1;
int no_loop = 0;
float normal_playback_rate = 2.0f;
fx.play(sfxId4, leftVolume, rightVolume, priority, no_loop, normal_playback_rate);
return false;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}
return true;
}
}
return true;
}
}
return true;
}
}