Jump to content

Multitouch & Soundpool


Franckdroid

Recommended Posts

Bonjour ,

Pour mon application de Beatmaker , je souhaiterais y mettre le multitouch afin de pouvoir faire plusieurs appuye de touches simultanées..

J'ai fouiller un peu partout et trouver un snippet de multitouch

http://www.passsy.de...-for-all-views/

J'aimerai coupler le multitouch avec ma fonction SoundPool mais c'est là que ça bloque.

Voici ce dont j'ai utiliser:

Pour le multitouch:

public class MultiTouchActivity extends Activity implements OnTouchListener {

private View parent;
private final ArrayList[] recentTouchedViewsIndex = new ArrayList[10];
private final ArrayList[] downTouchedViewsIndex = new ArrayList[10];
private final ArrayList<View> moveOutsideEnabledViews = new ArrayList<View>();
private int mTouchSlop = 24;
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());
  }
 }
}
private void dumpEvent(final 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
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
  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) {
 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) {
 touchedViews.add(view);
 possibleViews.addAll(getChildViews(view));
}
  }
 }
 return touchedViews;
}
@Override
public void onCreate(final Bundle instance) {
 super.onCreate(instance);
 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
 getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
 parent = findViewById(android.R.id.content).getRootView();
 parent.setOnTouchListener(this);
 mTouchSlop = ViewConfiguration.get(getApplicationContext())
.getScaledTouchSlop();
}
@Override
public boolean onTouch(final View v, final MotionEvent event) {
 // 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_MOVE) {
  for (int ptrIndex = 0; ptrIndex < event.getPointerCount(); ptrIndex++) {
// only one event for all move events.
dealEvent(ptrIndex, event, v, actionResolved);
Log.v("tag", "move" + ptrIndex);
;
  }
 } else {
  dealEvent(actionPointerIndex, event, v, actionResolved);
 }
 return true;
}
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);
}
}

ensuite voici ma fonction SoundPool

package de.passsy.multitouch;
import java.util.HashMap;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
public class MultitouchtestActivity extends MultiTouchActivity {
/** Called when the activity is first created. */
private AudioManager audio;
SoundPool soundPool;
HashMap<Integer, Integer> soundPoolMap;
int soundID = 1;
int button1;

[size=2][color=#646464][size=2][color=#646464]@Override[/color][/size][/color][/size]

[b][size=2][color=#7F0055][size=2][color=#7F0055]public[/color][/size][/color][/size][/b] [b][size=2][color=#7F0055][size=2][color=#7F0055]void[/color][/size][/color][/size][/b][size=2] onCreate([/size][b][size=2][color=#7F0055][size=2][color=#7F0055]final[/color][/size][/color][/size][/b][size=2] Bundle savedInstanceState) {[/size]

[size=2]getWindow().addFlags(WindowManager.LayoutParams.[/size]
[i][size=2][color=#0000C0][size=2][color=#0000C0]FLAG_FULLSCREEN[/color][/size][/color][/size][/i][size=2]);[/size]
[size=2]getWindow().clearFlags([/size]
[size=2]WindowManager.LayoutParams.[/size]
[i][size=2][color=#0000C0][size=2][color=#0000C0]FLAG_FORCE_NOT_FULLSCREEN[/color][/size][/color][/size][/i][size=2]);[/size]


[b][size=2][color=#7F0055][size=2][color=#7F0055]super[/color][/size][/color][/size][/b][size=2].onCreate(savedInstanceState);[/size]
[size=2]setContentView(R.layout.[/size][i][size=2][color=#0000C0][size=2][color=#0000C0]main[/color][/size][/color][/size][/i][size=2]);[/size]

setContentView(R.layout.main);
setAudio((AudioManager) getSystemService(Context.AUDIO_SERVICE));
soundPool = new SoundPool(50, AudioManager.STREAM_MUSIC, 100);
soundPoolMap = new HashMap<Integer, Integer>();
soundPoolMap.put(soundID, soundPool.load(this, R.raw.highhat, 1));

final Button button1 = (Button) findViewById(R.id.bouton1);

button1.setOnTouchListener(buttonPlay1OnTouchListener);


Button.OnTouchListener buttonPlay1OnTouchListener = new Button.OnTouchListener() {
 @Override
 public boolean onTouch(final View v, final MotionEvent Event) {
  // TODO Auto-generated method stub
  final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  final float curVolume = audioManager
 .getStreamVolume(AudioManager.STREAM_MUSIC);
  final float maxVolume = audioManager
 .getStreamMaxVolume(AudioManager.STREAM_MUSIC);
  final float leftVolume = curVolume / maxVolume;
  final float rightVolume = curVolume / maxVolume;
  final int priority = 0;
  final int no_loop = 0;
  final float normal_playback_rate = 1f;
  soundPool.play(soundID, leftVolume, rightVolume, priority, no_loop,
 normal_playback_rate);
  return false;

}


}

Le Probleme est que je fait de nouveau une utilisation de OnTouch (final View v,final Motion Event)

dans ma fonction du soundpool alors que j'utilise l'implémentation de OnTouch provenant de l'activité multitouch.

j'ai tester le snippet du multitouch sans soundpool et il fonctionne bien quand on crée les boutons de cette facon

button1.setOnTouchListener(this);

mais moi je suis obliger de le faire de cette facon

button1.setOnTouchListener(buttonPlay1OnTouchListener);

A partir de cela lorsque je fait action DOWN , j'entend un son et lors du Action UP ce meme son réapparait .. ce qui n'est pas normal..

donc voila je suis un peu embeter de ce coter la , si vous auriez une petite solution ce serait super

merci

cordialement

Link to comment
Share on other sites

Salut,

Bon, j'ai pas tout bien compris mais en gros, le problème se situe juste sur le fait que tu as un son à l'action down et au up ?

Si c'est cela, il suffit de filtrer l'action dans ton onTouch (c'est carrément dans l'exemple de l'API que tu utilises :D ).

if (event.getAction() == MotionEvent.ACTION_UP) {
   setText("I can recive Move events outside of my View");
}

Par contre, vu que tu fais du multitouch, tu auras peut-être besoin d'utiliser les actionmask ou je ne sais plus quel autre masque (voir la doc android ^^).

Si c'est autre chose, bin, j'ai po compris :D

PS : Utilise la balise CODE pour insérer du code... Là c'est imbitable :/

Link to comment
Share on other sites

Bonjour Merci de ta réponse:)

c'est vrai que sans les balises "code" c'était imbuvable.

En effet j'ai essayé de filtrer par rapport à l'action UP mais rien , aucun effet.

Lorsque je test le projet original du snippet multitouch , tout fonctionne , je peux appuyer sur plusieurs bouton en meme temps.

Des lors que je met ma fonction SoundPool ca plante.Plus de réaction ''multitouch''

- Dans l'activity du multitouch on y trouve la fonction OnTouch() qui implémente les boutons de l'activité SoundPool

La fonction multitouch comporte deja le Action Mask et fonctionne parfaitement vu que j'ai pu tester sur le projet original du multitouch.

En fait le réél probleme provient de mon écriture de la fonction SoundPool..

Dans le projet original du multitouch , les boutons sont écrits comme ceci: button1.setOnTouchListener(this);

et moi pour ma fonction SoundPool je suis obliger de l'écrire comme ceci : button1.setOnTouchListener(buttonPlay1OnTouchListener);

En fait le multitouch fonctionnera qui s'il y a le (This) .sur les boutons.

comment puis-je pallier a ce problème?

j' éspere avoir un peu mieu expliquer:)

Merci Beaucoup

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...