OnTouchListener

  • Antworten:11
Joachim Schoenfeld
  • Forum-Beiträge: 14

12.11.2018, 09:45:21 via Website

Hallo, steh da grade bischen auf dem Schlauch.
Mein Vorhaben ist es über den OnTouchListener mehrere Objekte(imageviews) frei zu bewegen.
Mit einem Objekt klappt das . Meine Frage ist, wie kann ich das mit mehreren objekten umsetzen. Unten der Code mit einem Objekt.

enter code here

public class MainActivity extends Activity implements View.OnTouchListener {

private ImageView mImageView01;
private ImageView mImageView02;
private ViewGroup mRrootLayout;
private int _xDelta;
private int _yDelta;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    mRrootLayout = (ViewGroup) findViewById(R.id.root);
    mImageView01 = (ImageView) mRrootLayout.findViewById(R.id.imageView01);
    //mImageView02 = (ImageView) mRrootLayout.findViewById(R.id.imageView02);

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(250, 250); //Default 150/150
    mImageView01.setLayoutParams(layoutParams);
    mImageView01.setOnTouchListener(this);

}
@Override
public boolean onTouch(View v, MotionEvent event) {

        final int X = (int) event.getRawX();
        final int Y = (int) event.getRawY();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                _xDelta = X - lParams.leftMargin;
                _yDelta = Y - lParams.topMargin;
                break;
            case MotionEvent.ACTION_UP:
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                break;
            case MotionEvent.ACTION_POINTER_UP:
                break;
            case MotionEvent.ACTION_MOVE:
                RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
                layoutParams.leftMargin = X - _xDelta;
                layoutParams.topMargin = Y - _yDelta;
                layoutParams.rightMargin = -250; //Default -250
                layoutParams.bottomMargin = -250;  // Default -250
                v.setLayoutParams(layoutParams);
                break;
        }

        mRrootLayout.invalidate();
        return true;
    }

}

Vielen Dank im voraus.
gruß Joachim

Kommentieren
Jokel
  • Forum-Beiträge: 1.530

12.11.2018, 11:23:21 via Website

Hallo willommen im Forum.
Versuche es mal so.
Auf jeden Fall brauch du für jede View eine Variablen zum zwischenspeichen der Position.
Für mehr als zwei würde ich es etwas anders machen mehr in Richtung oop. Aber für die zwei solte das so gehen.

public class MainActivity extends Activity implements View.OnTouchListener {

private ImageView mImageView01;
private ImageView mImageView02;
private ViewGroup mRrootLayout;
private int _xDelta1, _xDelta2;
private int _yDelta1, _yDelta2;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    mRrootLayout = (ViewGroup) findViewById(R.id.root);
    mImageView01 = (ImageView) mRrootLayout.findViewById(R.id.imageView01);
    mImageView02 = (ImageView) mRrootLayout.findViewById(R.id.imageView02);

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(250, 250); //Default 150/150
    mImageView01.setLayoutParams(layoutParams);
    mImageView01.setOnTouchListener(this);
    mImageView02.setLayoutParams(layoutParams);
    mImageView02.setOnTouchListener(this);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (v.getId()){
        case R.id.imageView01:
            moveView(v,evevent,1);
            break;
        case R.id.imageView02:
            moveView(v,evevent,2);
            break;
    }
    mRrootLayout.invalidate();
    return true;
}
void moveView(View v, MotionEvent event, int flag ){
    final int X = (int) event.getRawX();
    final int Y = (int) event.getRawY();
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
            if ( flag ==1){
                _xDelta1 = X - lParams.leftMargin;
                _yDelta1 = Y - lParams.topMargin;
            }else{
                _xDelta2 = X - lParams.leftMargin;
                _yDelta2 = Y - lParams.topMargin;
            }

            break;
        case MotionEvent.ACTION_UP:
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            break;
        case MotionEvent.ACTION_POINTER_UP:
            break;
        case MotionEvent.ACTION_MOVE:
            RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
            if ( flag ==1){
                layoutParams.leftMargin = X - _xDelta1;
                layoutParams.topMargin = Y - _yDelta1;
            }else{
                layoutParams.leftMargin = X - _xDelta2;
                layoutParams.topMargin = Y - _yDelta2;
            }
            layoutParams.rightMargin = -250; //Default -250
            layoutParams.bottomMargin = -250;  // Default -250
            v.setLayoutParams(layoutParams);
            break;
    }       
}

}

— geändert am 12.11.2018, 11:56:09

Hilfreich?
Joachim Schoenfeld
Kommentieren
Joachim Schoenfeld
  • Forum-Beiträge: 14

12.11.2018, 13:09:49 via Website

Hallo,
danke für die Antwort.

Ich müsste 15 ImageViews haben:-)
Mit dem "switch (v.getId())" hatte ich auch schon probiert,
da war dann allerdings vom 2ten ImageView nix zu sehen.

Werde es heute abend mal ausprobieren und melde mich dann wieder.

Hilfreich?
Kommentieren
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

12.11.2018, 14:43:14 via Website

Da du 15 imageViews hast, würde ich direkt über OOP gehen und mir die deltas als Struktur/Point im View#Tag speichern.
Dann kannst do ohne n-Cases auskommen und brauchst auch nicht 2n Variablen haben

— geändert am 12.11.2018, 14:43:27

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

12.11.2018, 14:47:32 via Website

Wenn du willst das es bei der zweiten View auch in die onklick Methode geht. Dann musst du auch den listner auf die View setzten.
Wenn du den nicht setzt kannst logischer Weise auch nichts bei v stehen.
Wie kann ich mir den dein layout überhaupt vorstellen.
Wieso setzt du die parms in der onCreate neu und nicht gleich in XML?

— geändert am 12.11.2018, 15:50:40

Hilfreich?
Kommentieren
Joachim Schoenfeld
  • Forum-Beiträge: 14

12.11.2018, 23:36:02 via Website

Wird auch nur ein ImageView angezeigt

Hilfreich?
Kommentieren
Joachim Schoenfeld
  • Forum-Beiträge: 14

12.11.2018, 23:36:57 via Website

Dann werd ich mir das OOP mal reinziehen :-)

Hilfreich?
Kommentieren
Joachim Schoenfeld
  • Forum-Beiträge: 14

12.11.2018, 23:42:19 via Website

die xml Datei kann ich hier nicht posten.
Deinen letzen Satz verstehe ich nicht so ganz.

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

13.11.2018, 07:24:32 via Website

Hallo

Wird auch nur ein ImageView angezeigt

Klar ist nur eine View in der Variablen „v“ und genau die was das Event ausgelöst hat.

Mit
„mImageView01.setOnTouchListener(this);“
„mImageView02.setOnTouchListener(this);“
setzt du den Listner für die ImageViews .

Beim berühren wird ein Event ausgelöst was in dem Listner ankommt, und ihm wird die View mitgegeben die das Event ausgelöst hat. Das hast du dann in der Variablen „v“ .

Wenn du das andere ImageView berürst wird dem „v“ das ImageView2 übergeben.
Beim berühren des View1 wird dir natürlich die View1 in der Variablen "v" übergeben.
Dies sollte aber so sein, wenn du den Listner auf beide oder alle Views gesetzt hast.

Oder willst du beim berühren einer View alle Views gleichzeitig bewegen?

RelativeLayout.LayoutParams(250, 250); //Default 150/150
mImageView01.setLayoutParams(layoutParams);

Hiermit machst du eigentlich nichts weiteres als die höhle und weite der View verändern ist das gleiche als ob du es in XML mit android:layout_width , android:layout_height machst.

— geändert am 13.11.2018, 08:05:10

Hilfreich?
Kommentieren
Joachim Schoenfeld
  • Forum-Beiträge: 14

13.11.2018, 08:24:44 via Website

nein , immer nur eins verschieben!

Hilfreich?
Kommentieren
Jokel
  • Forum-Beiträge: 1.530

13.11.2018, 09:35:47 via Website

Hallo so wird das wohl nicht gehen.
Habe die Doku noch mal gelesen.

Denn der OnTouchListener wird aus gelöst wenn eine Berührung des Bildschirms erfolgt.
In der Variablen „v“ bekommst du die View auf dem du den Listner gesetzt hast. Und das müsste die sein auf den du den Listner als letztes setz. In meinen Beispiel ImageView2.

Somit bekommst du immer ImageViwe2 und das Event.
Du musst nun selber an hand der Position raus finden über welche View du nun gerade bist.

Auch macht es mehr sinn den Listner auf das Layout zusetzen.

Als alternative könntest du einen longKlick benutzen um damit zb in einen Verschiebe Modus zu wechseln wo du nun mit den Positions Daten des OnTouchlister die View verschieben kannst.

Hilfreich?
Kommentieren
Joachim Schoenfeld
  • Forum-Beiträge: 14

13.11.2018, 10:22:22 via Website

Moin,

so funktioniert es jetzt,...die Layout.xml auch geändert/angepasst >>>
`
private View.OnTouchListener onTouchListener() {
return new View.OnTouchListener() {

        @Override
        public boolean onTouch(View view, MotionEvent event) {
            final int x = (int) event.getRawX();
            final int y = (int) event.getRawY();
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams)
                            view.getLayoutParams();
                    xDelta = x - lParams.leftMargin;
                    yDelta = y - lParams.topMargin;
                    break;
                case MotionEvent.ACTION_MOVE:
                    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
                            .getLayoutParams();
                    layoutParams.leftMargin = x - xDelta;
                    layoutParams.topMargin = y - yDelta;
                    layoutParams.rightMargin = 0;
                    layoutParams.bottomMargin = 0;
                    view.setLayoutParams(layoutParams);
                    break;
            }
            mainLayout.invalidate();
            return true;
        }
    };
}`

Danke für die Ansätze, die nächste Frage kommt bestimmt bald ;-)

gruß joachim

Hilfreich?
Kommentieren