Touch simultâneo em duas views[Android]

Save galerinha…

Bem é o seguinte… Estou desenvolvendo um apk onde o usuario terá a opção de clickar em dois “botões” ao mesmo tempo…

Este apk é para controlar o PC… ou seja… A pessoa poderia movimentar o mouse e “clickar” ao mesmo tempo…

Eu achei q isso estaria ativo normalmente no android… mas quando eu movimento o mouse e pressiono o botão para o click… ele só reconhece o touch da view que está movimentando o mouse…

Tem como ativar o “touch simultaneo”??

Grato pela atenção de todos!

Fiquem com DEUS:!:

Bom dia,

Em qual dispositivo vc esta testando sua app?

Como vc esta dividindo a tela, posta o layout pra gente verificar.

Layout:

[code]<?xml version="1.0" encoding="UTF-8"?>

    <TextView
        android:id="@+tvs/tvLocal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Local"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <lan.controlador.Joy
            android:id="@+joys/joyMouse"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginLeft="0dp"
            android:layout_weight="1" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1" >

                <Button
                    android:id="@+bts/btClick"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="Clickar" />

                <Button
                    android:id="@+bts/btClickR"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:text="Clickar" />

            </LinearLayout>

            <Button
                android:id="@+bts/btscrollUp"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="&#8593;" />

            <Button
                android:id="@+bts/btscrollDown"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="&#8595;" />

            <Button
                android:id="@+bts/btDigitar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:text="Digitar" />

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

[/code]
Classe Joy:

[code]package lan.controlador;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class Joy extends View {
Point pontoFinal, pontoMeio = null;
Paint paint;
int larg = getWidth();
int alt = getHeight();
ListenerJoy listener;
int sensibilidade = 10;

public Joy(Context context, AttributeSet attrs)
{
    super(context, attrs);
    
    pontoFinal = new Point(larg/2, alt/2);
    
    System.out.println("Sens: "+sensibilidade);
    
    iniciarPaint();
    
    setarListener();
}

public void iniciarPaint(){
	paint = new Paint();
	paint.setStrokeWidth(2); //Seta a "grossura" do Paint
}

public void setarListenerJoy(ListenerJoy LJ){
	listener = LJ;
}

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas)
{
	if(pontoMeio == null){
		larg = getWidth();
    	alt = getHeight();
    
    	pontoMeio = new Point(larg/2, alt/2);
    	
    	pontoFinal.set(pontoMeio.x, pontoMeio.y);
	}
	
	paint.setColor(Color.GREEN); //Seta a cor do Paint
	
	if(!isEnabled())
		paint.setColor(Color.rgb(92, 205, 92)); //Seta a cor do Paint
    
    canvas.drawRect(10, 10, larg-10, alt-10, paint);
    
    paint.setColor(Color.RED); //Seta a cor do Paint
    
    if(!isEnabled())
    	paint.setColor(Color.rgb(205, 92, 92)); //Seta a cor do Paint
    
    int tam = 15, x = 0, y = 0;
    
    if(pontoFinal.x > 0){
    	if(pontoFinal.x > larg){
    		x = larg;
    	}else{
    		x = pontoFinal.x;
    	}
    }
    
    if(pontoFinal.y > 0){
    	if(pontoFinal.y > larg){
    		y = larg;
    	}else{
    		y = pontoFinal.y;
    	}
    }
    
    canvas.drawRect(x-tam, y-tam, x+tam, y+tam, paint);
    
    super.onDraw(canvas);
}

public void setarListener(){
	setOnTouchListener(new View.OnTouchListener() {
		
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if(event.getAction() == MotionEvent.ACTION_DOWN){}
	        
	        if(event.getAction() == MotionEvent.ACTION_MOVE){
	        	pontoFinal.set((int) event.getX(), (int) event.getY());
	        	
	        	listener.onMove();
	        	
	        	invalidate();
	        }
	        
	        if(event.getAction() == MotionEvent.ACTION_UP){
	        	pontoFinal.set(pontoMeio.x, pontoMeio.y);
	        	
	        	listener.onMove();
	        	
	        	invalidate();
	        }
			return true;
		}
	});
}

public int getxAxis(){
	int ret = 0;
	
	int prop = (larg/2)/sensibilidade;
	
	if(pontoFinal.x > 0 && pontoFinal.x < larg){
		ret = pontoFinal.x - pontoMeio.x;
	}
	
	if(pontoFinal.x > larg){
		ret = larg/2;
	}
	
	if(pontoFinal.x < 0){
		ret = 0-(larg/2);
	}
	
	return ret/prop;
}

public int getyAxis(){
	int ret = 0;
	
	int prop = (alt/2)/sensibilidade;
	
	if(pontoFinal.y > 0 && pontoFinal.y < alt){
		ret = pontoFinal.y - pontoMeio.y;
	}
	
	if(pontoFinal.y > alt){
		ret = alt/2;
	}
	
	if(pontoFinal.y < 0){
		ret = 0-(alt/2);
	}
	
	return ret/prop;
}

}
[/code]

Estou testando o codigo num Galaxy Y :wink:

Fica com DEUS e obrigado pela atenção:!:

Uma View pode receber os dois toques, mas duas views não recebem os toques separados.

Para resolver isto eu usei uma classe que achei na internet para dispachar os eventos para varias Views.

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);
        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);
    }
}

Vou testar aqui…

Depois posto se deu certo…