Wie gehe ich mit touch-Ereignisse richtig in android?

Rahmen des Projekts

Wenn ein Benutzer berührt den Android-Bildschirm mit zwei Fingern, und ziehen Sie ein "Rahmen" bei jeder Berührung Position mit einem "cursor" für jeden frame. Jeder frame eine benutzerdefinierte Schieberegler, bewegt sich der cursor nach oben und unten. Den ganzen Weg bis zu 100%, Mitte 0% und alle dem Weg nach unten werden -100%. Diese Steuern werden kleine Motoren, ähnlich dem tank drehen, jeder touch-Steuerung, die einen separaten motor (senden von Signalen über bluetooth). Nach zwei touch-und alles gezeichnet ist, will ich in der Lage, heben Sie entweder die finger, SONDERN halten Sie den cursor auf was auch immer Ort, es war die Letzte an, während die anderen finger frei zu bewegen und seinen cursor. Wenn der Letzte finger ist abgehoben, alles "versteckt" und setzt die auf 0%.

Funktionalität Wollte

  1. Auf zwei-finger-touch, ziehen, trennen .pngs unter der touch-Position
  2. Nach den frames und der Cursor gezeichnet werden, behalten Sie den überblick, wo Sie relativ zu dem Rahmen zu bestimmen, der Anteil.
  3. Wenn ein finger abgehoben, zu halten, dass die Finger der cursor an der letzten bekannten Position, aber die anderen finger bewegen kann, es ist cursor. Auch wenn die finger wieder down es in der Lage sein sollten, bewegen Sie den cursor wieder.
  4. Wenn beide Finger sind abgehoben von dem Bildschirm, blendet alles aus und reset-Prozentsätze 0%

Funktionalität Erhalten

  • Ich kann zeichnen der Rahmen und Cursor auf multitouch -
  • Positionen und Prozentsätze funktionieren
  • Cursor richtig bewegen

, Was nicht funktioniert

  • Ich bin nicht sicher, ob ich sollte eine custom-Klasse, die Griffe sowohl auf touch-als Ereignis oder wenn ich 2 Instanzen des benutzerdefinierten Klasse jeden Umgang mit Ihren eigenen touch-Ereignisse (ich habe beide ausprobiert, der einzige Weg, bekomme ich keine "echte" Funktion ist mit 1 benutzerdefinierten Klasse zur Verarbeitung von touch-events, die andere Weise nicht funktioniert, wie gedacht)
  • Wenn ich nur 1 custom-Klasse, Es funktioniert Super, aber ich habe es "verstecken" sich alles, wenn die beiden die Finger nicht auf dem Bildschirm, und manchmal android registriert, dass ich den finger gehoben aus dem Bildschirm, und das verursacht mir eine Menge Fragen, wenn die frames zu verstecken, dann wieder auftauchen in einem anderen Ort
  • Wenn ich 2 benutzerdefinierte Klassen, die ich berühren jede benutzerdefinierte Klasse hat Ihren eigenen touch-event, und ich würde nicht sorgen zu machen über multitouch, wenn ich teilen Sie die Klassen gleichmäßig auf dem Bildschirm. War dies nicht der Fall, müssen noch viel mit multitouch

Kann mir jemand erklären, wie android behandelt Ihre touch-Ereignisse. von dem, was ich getan habe, es scheint, wenn ich lay down finger 1, finger 2, der erste finger registrieren Sie einen "ACTION_DOWN" und mit dem zweiten register "ACTION_POINTER_2_DOWN", ABER wenn ich das Leben von meinem ersten finger, meine zweite finger ist "degradiert" und jetzt alle die Ereignisse meines zweiten finger Register jedoch nicht im Zusammenhang mit "ACTION_POINTER_2", sondern "ACTION_DOWN, ACTION_UP, etc". Ist das richtig?

TouchUI.java

    package com.robota.android;

    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.ImageView;

public class TouchUI extends ImageView {

public static final String LEFT_TOUCHUI = "com.robota.android:id/leftTouchUI";
public static final String RIGHT_TOUCHUI = "com.robota.android:id/rightTouchUI";
private String whoAmI = new String();
private MyPoints framePts = new MyPoints();
private MyPoints cursorPts = new MyPoints();
private Bitmap frame;
private Bitmap cursor;
private int frameWidth;
private int frameHeight;
private int cursorHeight;
private boolean pointerDown = false;
private int dy;

public TouchUI(final Context context, final AttributeSet as){
    super(context, as);
    Log.d("TouchUI", getResources().getResourceName(this.getId()));
    whoAmI = new String(getResources().getResourceName(this.getId()));
    if(whoAmI.equals(LEFT_TOUCHUI)){
        frame = BitmapFactory.decodeResource(getResources(), R.drawable.tank_left);
    }else if(whoAmI.equals(RIGHT_TOUCHUI)){
        frame = BitmapFactory.decodeResource(getResources(), R.drawable.tank_right);
    }
    cursor = BitmapFactory.decodeResource(getResources(), R.drawable.cursor);
    frameWidth = frame.getWidth();
    frameHeight = frame.getHeight();
    cursorHeight = cursor.getHeight();
}

public void determinePointers(int x, int y){
        framePts.setOrigin(x-frameWidth/2, y-frameHeight/2);
        cursorPts.setOrigin(x-frameWidth/2, y-frameHeight/2);
}

@Override
public boolean onTouchEvent(MotionEvent e){
    int x = 0;
    int y = 0;
    Log.d("TouchUI", ">>>>> " + whoAmI);
    if(e.getAction() == MotionEvent.ACTION_DOWN){
        determinePointers(x,y);
        pointerDown = true;
    }else if(e.getAction() == MotionEvent.ACTION_UP){
        pointerDown = false;
    }else if(e.getAction() == MotionEvent.ACTION_MOVE){
        dy = (int)e.getY()-framePts.getY();
        if(dy <= 0){
            dy=0;
        }else if(dy+cursorHeight/2 >= frameHeight){
            dy=frameHeight;
        }
        sendMotorSpeed(dy);
    }
    return true;
}

public void sendMotorSpeed(int dy){
    float motor = dy;
    motor-=frameHeight;
    motor*=-1;

    motor = (motor/frameHeight)*255;

    PacketController.updateMotorSpeeds(whoAmI, (int)motor);
}

public void onDraw(Canvas canvas){
    if(pointerDown){//twoDown){
        canvas.drawBitmap(frame, framePts.getX(), framePts.getY(), null);
        canvas.drawBitmap(cursor, cursorPts.getX(), (cursorPts.getY()+dy), null);
    }
    invalidate();
}

private class MyPoints{

    private int x = -100;
    private int y = -100;
    private int deltaY = 0;;

    public MyPoints(){
        this.x = 0;
        this.y = 0;
    }

    public int getX(){
        return this.x;
    }

    public int getY(){
        return this.y;
    }

    public void setOrigin(int x, int y){
        this.x = x;
        this.y = y;
    }

    public int getDeltaY(){
        return deltaY;
    }

    public void setDeltaY(int newY){
        deltaY = (newY-y);
        Log.d("TouchUI", "DY: " + deltaY);
    }
}
}

Main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parentLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout android:orientation="horizontal"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <com.robota.android.TouchUI xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/leftTouchUI"
        android:background="#0000"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_weight="1">
    </com.robota.android.TouchUI>
    <com.robota.android.TouchUI xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/rightTouchUI"
        android:background="#0000"
        android:layout_height="match_parent"
        android:layout_width="wrap_content"
        android:layout_weight="1">
    </com.robota.android.TouchUI>
</LinearLayout>

RobotController.java (Haupt-Activity-Klasse)

    package com.robota.android;

    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothDevice;
    import android.content.ActivityNotFoundException;
    import android.content.Intent;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.Window;
    import android.widget.ScrollView;
    import android.widget.TextView;
    import android.widget.Toast;

public class RobotController extends Activity {
//Tag used to keep track of class in the Log
private static final String TAG = "robotController_new";
//Boolean to debugging
private static final boolean D = true;

//Intent request codes
private static final int DISCONNECT_DEVICE = 1;
private static final int CONNECT_DEVICE = 2;
private static final int REQUEST_ENABLE_BT = 3;

//Handler Codes
public static final int MESSAGE_READ = 1;
public static final int MESSAGE_WRITE = 2;

//Local Bluetooth Adapter
private BluetoothAdapter bluetoothAdapter = null;
//Bluetooth Discovery and Datahandler
private BluetoothComm btComm = null;

//Debug's TextView, this is where strings will be written to display
private TextView tv;
private ScrollView sv;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    if(D) Log.d(TAG, "++ON CREATE++");
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);

    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    if(bluetoothAdapter == null){
        if(D) Log.d(TAG, "NO BLUETOOTH DEVICE");
        Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_SHORT).show();
        finish();
        return;
    }

    PacketController.controller = this;
}


public void onStart(){
    super.onStart();
    if(D) Log.d(TAG, "++ON START++");

    if(!bluetoothAdapter.isEnabled()){
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    }else{
        //Start BluetoothComm
        if(btComm == null){
            setupComm();
        }
    }
}

/**
 * Creates new Bluetooth Communication
 */
private void setupComm(){
    if(D) Log.d(TAG, "+++setupComm+++");
    btComm = new BluetoothComm(this, handler);
}

private void connectDevice(Intent data){
    if(D) Log.d(TAG, "+++connectDevice+++");
    String addr = data.getExtras()
        .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
    BluetoothDevice device = bluetoothAdapter.getRemoteDevice(addr);
    if(D) Log.d(TAG,"REMOTE ADDR: "+ addr);
    btComm.connect(device);
}

private void disconnectDevice(){
    if(D) Log.d(TAG, "---disconnectDevice---");
    if(btComm.getState() == btComm.STATE_CONNECTED){
        btComm.disconnect();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    //super.onCreateOptionsMenu(menu);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Intent serverIntent = null;
    switch(item.getItemId()){       
    case R.id.insecure_connect_scan:
        //Launch the DeviceListActivity to see devices and do scan
        serverIntent = new Intent(this, DeviceListActivity.class);
        try{
            startActivityForResult(serverIntent, CONNECT_DEVICE);
        }catch(ActivityNotFoundException activityNotFound){
            Log.e(TAG, "Could not start DeviceListActivity(Insecure)");
        }
        return true;
    }
    return false;
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
    switch(requestCode){
    case CONNECT_DEVICE:
        if(resultCode == Activity.RESULT_OK){
            connectDevice(data);
        }
        break;
    case DISCONNECT_DEVICE:
        if(resultCode == Activity.RESULT_OK){
            disconnectDevice();
        }
        break;
    }
}

public Handler getHandler(){
    return this.handler;
}

public BluetoothComm getBtComm(){
    return this.btComm;
}

//The Handler that gets information back from the BluetoothChatService
private final Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        if(D) Log.d(TAG, "check message");
        switch (msg.what) {
        case MESSAGE_READ:
            if(D) Log.d(TAG, "trying to read message");
            byte[] readBuf = (byte[]) msg.obj;
            //construct a string from the valid bytes in the buffer
            String readMessage = new String(readBuf, 0, msg.arg1);
            if(D) Log.d(TAG, "bytes: " + readBuf + " arg1: " + msg.arg1 + " Message: " + readMessage);
            tv.append(readMessage);
            break;
        case MESSAGE_WRITE:
            if(D) Log.d(TAG, "trying to send message");
            String sendMessage = new String(String.valueOf(msg.obj));
        }
    }
};
}

Andere Klassen nicht aufgeführt, ich konnte nicht glauben, gebraucht zu werden, aber wenn Sie gebraucht werden, lasst es mich bitte wissen.

Jede Hilfe ist sehr willkommen

InformationsquelleAutor heater | 2011-05-31

Schreibe einen Kommentar