I’m posting this request for help here so I can just post a link and not have to clutter up everybody’s forum.
So here’s the dealio -
I need to control multiple sliders (seekbars) at the same time to send bluetooth serial commands to another device.
I created one version that worked to send the serial commands, but wasn’t multitouch.
I’ve found several examples of how to setup a multi-touch capable view but now I cannotĀ find where to handle click events when the views are combined in this way.
Here is a stripped down version of what I have so far.
I just need to understand how to create a function that will execute when I hit a button or change a value on the seek bar. If I could just change the value of the textView I think I could figure the rest out.
Any help or direction would be appreciated.
~MTouch.java
package funkboxing.mtouch;
import funkboxing.mtouch.R;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;
public class MTouch extends MultiTouchActivity {
/** Called when the activity is first created. */
private Button btn1;
private Button btn2;
private SeekBar seekbar1;
private SeekBar seekbar2;
private TextView tview1;
private TextView tview2;
private TextView tview3;
private TextView tview4;
@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.main);
btn1 = (Button) findViewById(R.id.button1);
btn1.setOnTouchListener(this);
btn2 = (Button) findViewById(R.id.button2);
btn2.setOnTouchListener(this);
seekbar1 = (SeekBar) findViewById(R.id.seekbar1);
seekbar1.setOnTouchListener(this);
addMoveOutsideEnabledViews(seekbar1);
seekbar2 = (SeekBar) findViewById(R.id.seekbar2);
seekbar2.setOnTouchListener(this);
addMoveOutsideEnabledViews(seekbar2);
tview1 = (TextView) findViewById(R.id.textView1);
tview2 = (TextView) findViewById(R.id.textView2);
tview3 = (TextView) findViewById(R.id.textView3);
tview4 = (TextView) findViewById(R.id.textView4);
}
}
~MultiTouchActivity.java
package funkboxing.mtouch;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
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 moveOutsideEnabledViews = new ArrayList();
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 hoverViews = getTouchedViews(rawX, rawY);
if (actionResolved == MotionEvent.ACTION_DOWN) {
downTouchedViewsIndex[actionPointerID] = (ArrayList) hoverViews
.clone();
}
// deletes all views which where not clicked on ActionDown
if (downTouchedViewsIndex[actionPointerID] != null) {
final ArrayList tempViews = (ArrayList) hoverViews
.clone();
tempViews.removeAll(downTouchedViewsIndex[actionPointerID]);
hoverViews.removeAll(tempViews);
}
if (recentTouchedViewsIndex[actionPointerID] != null) {
final ArrayList recentTouchedViews = recentTouchedViewsIndex[actionPointerID];
final ArrayList shouldTouchViews = (ArrayList) hoverViews
.clone();
if (!shouldTouchViews.containsAll(recentTouchedViews)) {
shouldTouchViews.removeAll(recentTouchedViews);
shouldTouchViews.addAll(recentTouchedViews);
final ArrayList outsideTouchedViews = (ArrayList) 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 getChildViews(final View view) {
final ArrayList views = new ArrayList();
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 getTouchedViews(final int x, final int y) {
final ArrayList touchedViews = new ArrayList();
final ArrayList possibleViews = new ArrayList();
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);
requestWindowFeature(Window.FEATURE_NO_TITLE);
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);
}
}
~main.xml
[...] Here is a stripped down version of what I have so far. http://funkboxing.com/wordpress/?p=1355 [...]