我正在尝试制作钢琴应用程序。
如何在多个键(VIEWS)上滑动并让它们播放音调? 每把钥匙都有自己的声音。
这会产生很大的性能差异吗?
目前正在运作:
以下是其中一个关键:
keyC1.setOnTouchListener(new View.OnTouchListener() {
private Rect rect; // Variable rect to hold the bounds of the view
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
// Finger started pressing --> play sound in loop mode
rect = new Rect(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
Sound_tonC1();
keyC1.setBackgroundColor(getResources().getColor(R.color.lightgray));
break;
case MotionEvent.ACTION_MOVE:
// Finger released --> stop playback
if(!rect.contains(v.getLeft() + (int) event.getX(), v.getTop() + (int) event.getY())){
// User moved outside bounds
keyC1.setBackgroundResource(R.drawable.piano_whitekey);
if(!sustain){
spool.stop(streamID_C1);
}
}
break;
case MotionEvent.ACTION_UP:
// Finger released --> stop playback
keyC1.setBackgroundResource(R.drawable.piano_whitekey);
if(!sustain){
spool.stop(streamID_C1);
}
break;
}
return true;
}
});
答案 0 :(得分:1)
要理解的一件事是,当您按下一个对象并将手指从对象上移开时,被调用的事件是一个ACTION_CANCEL事件。这就是为什么当您按下应用程序中的任何元素但将手指滑离应用程序时,您将要执行的操作不会发生。因此,您应该在代码中处理cancel事件,并在此情况下放置ACTION_UP代码:
keyC1.setOnTouchListener(new View.OnTouchListener() {
boolean keyIsPressed = false;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Finger started pressing --> play sound in loop mode
Sound_tonC1();
keyIsPressed = true;
keyC1.setBackgroundColor(getResources().getColor(R.color.lightgray));
break;
case MotionEvent.ACTION_CANCEL:
// Finger released --> stop playback
keyC1.setBackgroundResource(R.drawable.piano_whitekey);
if(!sustain){
keyIsPressed = false;
spool.stop(streamID_C1);
}
break;
case MotionEvent.ACTION_UP:
// Finger released --> stop playback
keyC1.setBackgroundResource(R.drawable.piano_whitekey);
if(!sustain){
keyIsPressed = false;
spool.stop(streamID_C1);
}
break;
case MotionEvent.ACTION_MOVE:
// Finger is moving on key --> start playback if the key is not already played
if(!keyIsPressed) {
Sound_tonC1();
keyIsPressed = true;
keyC1.setBackgroundColor(getResources().getColor(R.color.lightgray));
}
}
return true;
}
});
注意:使用ACTION_CANCEL并删除ACTION_MOVE,因为您不需要处理某个键的移动事件,只需按下该键并将其释放即可。
您的代码未检测到手指何时离开该键的原因是因为一旦触摸事件离开该区域,您的对象就不再接收任何事件。希望这有帮助。