我尝试使用多点触控制作应用程序,并使用以下代码:
它可以工作,但我遇到了问题,因为在我的应用程序中,我有 HorizontalScrollView (HSV),当我从 HSV 开始按下按钮时,我View.getId()
在“downTouchedViewsIndex”中有按钮 Id (),但是当我滚动我的 HSV并按我只有布局的 ID 的任何按钮 - 与按钮无关。
我的触摸码:
package com.lacrima.pianoo;
public class MainActivity extends Activity implements SeekBar.OnSeekBarChangeListener, OnTouchListener {
static private String TAG = "MainActivity";
public 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 List<Integer> list = new ArrayList<Integer>();
private final int mTouchSlop = 24;
AssetFileDescriptor des; // deskryptor do opisu wczytywanego pliku muzycznego (miejsce gdzie jesta zapisany dlugość i inne takie)
MediaPlayer[] mp = new MediaPlayer[36];// = new MediaPlayer();
//Pierwsza oktawa
Button button1, button2, button3, button4, button5, button6, button7;
Button button1_5, button2_5, button4_5, button5_5, button6_5;
//Druga oktawa
Button button8, button9, button10, button11, button12, button13, button14;
Button button8_5, button9_5, button11_5, button12_5, button13_5;
//Trzecia oktawa
Button button15, button16, button17, button18, button19, button20, button21;
Button button15_5, button16_5, button18_5, button19_5, button20_5;
SamplePlayer sound;
Integer[] soundIDs = new Integer[36];
private boolean[] whitePlays = new boolean[21];
private boolean[] blackPlays = new boolean[15];
private View[] whiteViews = new View[21];
private View[] blackViews = new View[15];
private int lastButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //Ustawienie ekranu horuzontalnie na sztywno
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
parent = findViewById(android.R.id.content).getRootView();
parent.setOnTouchListener(this);
SeekBar seek = (SeekBar) findViewById(R.id.seekBar);
final LockedHorizontalScrollView hsv = (LockedHorizontalScrollView)findViewById(R.id.hsv);
seek.setMax(948);
seek.setProgress(474);
seek.setOnSeekBarChangeListener(this);
hsv.post(new Runnable() {
@Override
public void run() {
hsv.scrollTo(474, 0);
}
});
sound = new SamplePlayer(this);
falsePlays();
buttonListeners();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
LockedHorizontalScrollView hsv = (LockedHorizontalScrollView)findViewById(R.id.hsv);
hsv.scrollTo(progress, 0);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
//uruchamiane w momencie kliknięcia na suwak
Log.d(TAG, "Tracking on");
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
//uruchamiane w momencie odkliknięcia suwaka
Log.d(TAG, "Tracking off");
}
@Override
protected void onDestroy() {
sound.release();
super.onDestroy();
}
@Override
public boolean onTouch(View v, 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_DOWN || actionResolved == MotionEvent.ACTION_UP
|| actionResolved == MotionEvent.ACTION_CANCEL) {
dealEvent(actionPointerIndex, event, v, actionResolved);
}
return true;
}
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();
lastButton = hoverViews.get(k-1).getId();
}
if(actionResolved == MotionEvent.ACTION_UP){
int k = hoverViews.size();
Log.d("klop", "Odklijniecie: " + hoverViews.get(k-1).getId());
lastButton = eventView.getId();
}
// 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;
}
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())) {
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 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;
}
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 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);
}
public void addMoveOutsideEnabledViews(final View view) {
moveOutsideEnabledViews.add(view);
}
和 xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#0A0A0A"
android:orientation="vertical" >
<SeekBar
android:id="@+id/seekBar"
android:layout_width="fill_parent"
android:layout_height="53dp" />
<com.lacrima.pianoo.LockedHorizontalScrollView
android:id="@+id/hsv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<Button...
</RelativeLayout>
</com.lacrima.pianoo.LockedHorizontalScrollView>
</LinearLayout>
我的代码很长,所以我把它放在 Dropbox(整个项目)上,你可以看到发生了什么