Добавление жеста перелистывания к просмотру изображения - Android

Хорошо, я ссылался на код здесь: Обнаружение жеста перелистывания в макете сетки

но никак не могу заставить его работать. В моей основной деятельности я определяю простое изображение. Я хочу обнаружить бросок на изображении. Вот мой код ниже. Метод onclick внизу пуст. Это из-за этого? Я оставил это поле пустым, потому что в другом примере кода это не то, что мне нужно. Я просто хочу, чтобы всплыл простой тост с надписью «Брось вправо» или «Брось влево».

public class GestureRightLeft extends Activity implements OnClickListener  {

    ImageView peek;

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private GestureDetector gestureDetector;
    View.OnTouchListener gestureListener;

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

        peek =(ImageView) findViewById(R.id.peek);
        peek.setImageResource(R.drawable.bluestrip);

        gestureDetector = new GestureDetector(new MyGestureDetector());
        gestureListener = new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (gestureDetector.onTouchEvent(event)) {
                    return true;
                }
                return false;
            }
        };
    }

    class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;
                // right to left swipe
                if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    Toast.makeText(GestureRightLeft.this, "Left Swipe", Toast.LENGTH_SHORT).show();
                }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    Toast.makeText(GestureRightLeft.this, "Right Swipe", Toast.LENGTH_SHORT).show();
                }
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }

    @Override
    public void onClick(View v) {}
}

person Ryan    schedule 04.11.2010    source источник
comment
См. Также Как добавить детектор жестов к просмотреть в Android   -  person Suragch    schedule 12.07.2017


Ответы (7)


Вот самая простая рабочая версия flinger, которую я могу придумать. Фактически вы можете привязать его к любому компоненту, а не только к ImageView.

public class MyActivity extends Activity {
    private void onCreate() {
        final GestureDetector gdt = new GestureDetector(new GestureListener());
        final ImageView imageView  = (ImageView) findViewById(R.id.image_view);
        imageView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(final View view, final MotionEvent event) {
                gdt.onTouchEvent(event);
                return true;
            }
        });
    }               

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    private class GestureListener extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Right to left
            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Left to right
            }

            if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Bottom to top
            }  else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) {
                return false; // Top to bottom
            }
            return false;
        }
    }
}

Однако никакой активности onClickListener (если вам не нужно ловить какие-либо действия onclick), он захватывает не только горизонтальные, но и вертикальные (просто удалите вертикальную часть, если она вам не нужна), а горизонтальные смахивания имеют приоритет, как вы можете видеть. В местах, где метод возвращается (ну, где мои комментарии), просто вызовите свой метод или что-то еще :)

person Alex Orlov    schedule 04.11.2010
comment
Вместо этого используйте final GestureDetector gdt = GestureDetector(this, new GestureListener()); для разработчиков . android.com/reference/android/view/ - person Richard; 11.04.2013
comment
Это больше похоже на пейджинг. Хороший пример подбрасывания можно найти здесь: developer.android.com/training / custom-views / - person Snicolas; 03.05.2013
comment
@Radu, прочтите ссылку, предоставленную @Snicolas. Вы должны переопределить onDown и вернуть истину. - person prodaea; 22.07.2015
comment
Я не совсем понимаю код, но, IMO, это не может быть правильным, потому что onFling возвращает false во всех путях выполнения. - person hgoebl; 14.01.2017

Попробуй это

imageView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return false;
            }
            return true;
        }
  });
person Pavan    schedule 08.02.2011
comment
+1, спасибо, чувак, у меня это сработало .. я возвращаю true вместо false. теперь моя проблема решена - person Ganapathy C; 05.05.2011
comment
@contactmeandroid внутри условия if также я возвращаю true; у меня это сработало. - person Ganapathy C; 28.10.2013
comment
@Ganapathy Это сработало, но я хотел перетащить изображение, но не смог. - person Srikanth Pai; 28.10.2013
comment
Вам может помочь структура перетаскивания в Android. developer.android.com/ руководство / themes / ui / drag-drop.html - person Ganapathy C; 28.10.2013
comment
Упрощенный возврат! MGestureDetector.onTouchEvent (motionEvent); - person Pedro Varela; 23.08.2017

некоторые из предварительных условий

1) метод setonClick

image.setOnClickListener(this);

2) установите обнаружение жестов в onTouch ()

image.setOnTouchListener(new OnTouchListener() {
    GestureDetector gestureDetector = new GestureDetector(new SwingGestureDetection((mContext),image,a));
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }
});

3) создать класс SwingGestureDetection и реализовать весь метод

@Override
public boolean onFling(MotionEvent start, MotionEvent finish, float arg2,float arg3) {
    if (start.getRawX() < finish.getRawX()) {
        System.out.println("next...swing");
    } else {
        System.out.println("previois...swing");
    }
}

4) передайте изображение в конструктор

public SwingGestureDetection(Context con,ImageView image,int pos) {
    mContext = con;
    this.image = image;
    this.position = pos;
}

Для меня это идеальная работа. Если есть запрос, то ставьте комментарий.

person Harshid    schedule 09.02.2013

Попробуйте прочитать: http://illusionsandroid.blogspot.com/2011/05/adding-fling-gesture-listener-to-view.html.

Это позволяет вам отделить реализацию вашей активности от вашего настраиваемого слушателя. Это просто рефакторинг решения, о котором сообщил Алекс Орлов.

person alessio.cocciolo    schedule 15.11.2011

Если вам не нравится создавать отдельный класс или усложнять код,
Вы можете просто создать переменную GestureDetector внутри OnTouchListener и упростить код

namVyuVar может быть любым именем View, на котором вам нужно установить список

namVyuVar.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View view, MotionEvent MsnEvtPsgVal)
    {
        flingActionVar.onTouchEvent(MsnEvtPsgVal);
        return true;
    }

    GestureDetector flingActionVar = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener()
    {
        private static final int flingActionMinDstVac = 120;
        private static final int flingActionMinSpdVac = 200;

        @Override
        public boolean onFling(MotionEvent fstMsnEvtPsgVal, MotionEvent lstMsnEvtPsgVal, float flingActionXcoSpdPsgVal, float flingActionYcoSpdPsgVal)
        {
            if(fstMsnEvtPsgVal.getX() - lstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Right to Left fling

                return false;
            }
            else if (lstMsnEvtPsgVal.getX() - fstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Left to Right fling

                return false;
            }

            if(fstMsnEvtPsgVal.getY() - lstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Bottom to Top fling

                return false;
            }
            else if (lstMsnEvtPsgVal.getY() - fstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac)
            {
                // TskTdo :=> On Top to Bottom fling

                return false;
            }
            return false;
        }
    });
});
person Sujay U N    schedule 30.05.2017

Если вы ищете такой метод, как ImageView.setOnGestureListener, его нет. Вы можете посмотреть исходный код Android. Лучше всего обработать это в onTouch () объекта View.

Это самый простой GestureDetector, который я могу сделать.

У меня есть класс GenesMotionDetector.java. Вот его код:

package gene.com.motioneventssample;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

public class GenesMotionDetector extends Activity implements GestureDetector.OnGestureListener {
    private GestureDetector gestureScanner;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.nothing);
        gestureScanner= new GestureDetector(getBaseContext(),this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent me) {
        System.out.println("Inside onTouchEvent() of GenesMotionDetector.java");
        return gestureScanner.onTouchEvent(me);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        System.out.println("Inside onDown() of GenesMotionDetector.java");
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        System.out.println("Inside onFling() of GenesMotionDetector.java");
        return true;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        System.out.println("Inside onLongPress() of GenesMotionDetector.java");
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        System.out.println("Inside onScroll() of GenesMotionDetector.java");
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {
        System.out.println("Inside onShowPress() of GenesMotionDetector.java");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        System.out.println("Inside onSingleTapUp() of GenesMotionDetector.java");
        return true;
    }
}

Соответствующий файл макета XML для этого класса - ничего.xml. Вот его код:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/screen"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/text"
        android:background="#17528c"
        android:text="testing"
        android:layout_width="100dp"
        android:layout_height="200dp" />

    <ImageView
        android:id="@+id/image"
        android:background="#f8af20"
        android:layout_width="100dp"
        android:layout_height="200dp" />
</LinearLayout>

Теперь, взяв простейший GestureDetector, который я могу сделать (сверху), и изменив его так, как вы хотите, я получил следующее:

package gene.com.motioneventssample;

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.widget.ImageView;

public class GenesMotionDetector3 extends Activity implements GestureDetector.OnGestureListener {
    private GestureDetector gestureScanner;
    ImageView mView3;

    View.OnTouchListener gestureListener;
    MotionEvent initialME, finalME;
    private VelocityTracker mVelocityTracker = null;

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


        mView3 = (ImageView) findViewById(R.id.image);

        // Gesture detection
        gestureScanner = new GestureDetector(getBaseContext(), this);

        gestureListener = new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch(event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        initialME= event;

                        if(mVelocityTracker == null) {
                            // Retrieve a new VelocityTracker object to watch the velocity of a motion.
                            mVelocityTracker = VelocityTracker.obtain();
                        }
                        else {
                            // Reset the velocity tracker back to its initial state.
                            mVelocityTracker.clear();
                        }
                        // Add a user's movement to the tracker.
                        mVelocityTracker.addMovement(event);

                        break;
                    case MotionEvent.ACTION_MOVE:
                        mVelocityTracker.addMovement(event);
                        // When you want to determine the velocity, call
                        // computeCurrentVelocity(). Then call getXVelocity()
                        // and getYVelocity() to retrieve the velocity for each pointer ID.
                        mVelocityTracker.computeCurrentVelocity(1000);
                        break;
                    case MotionEvent.ACTION_UP:
                        finalME=event;
                        break;
                    case MotionEvent.ACTION_CANCEL:
                        // Return a VelocityTracker object back to be re-used by others.
                        mVelocityTracker.recycle();
                        break;
                }
                return onFling(initialME, finalME, mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
                //return false;
            }
        };

        mView3.setOnTouchListener(gestureListener);
    }

    @Override
    public boolean onTouchEvent(MotionEvent me) {
        System.out.println("Inside onTouchEvent() of GenesMotionDetector.java");

        return gestureScanner.onTouchEvent(me);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        System.out.println("Inside onDown() of GenesMotionDetector.java");
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        System.out.println("Inside onFling() of GenesMotionDetector.java");
        System.out.println("e1= "+ e1);
        System.out.println("e2= "+ e2);
        System.out.println("velocityX= "+ velocityX);
        System.out.println("velocityY= "+ velocityY);
        return true;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        System.out.println("Inside onLongPress() of GenesMotionDetector.java");
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        System.out.println("Inside onScroll() of GenesMotionDetector.java");
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {
        System.out.println("Inside onShowPress() of GenesMotionDetector.java");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        System.out.println("Inside onSingleTapUp() of GenesMotionDetector.java");
        return true;
    }
}

С таким же успехом вы можете просто обрабатывать все в onTouch (). Я в основном получаю жесты в onTouch и передаю их onFling ().

person Gene    schedule 20.11.2014

Создайте свой макет с помощью ImageView. Добавьте setOnTouchListenerto imageView.imageview.setOnTouchListener(this).add нереализованный метод View.OnTouchListener. Затем onTouch метод, который вы можете реализовать в своей гостевой логике. Этот пример сообщает вам гостевое управление слева направо и справа налево,

float x1,x2;
float y1, y2;

@Override
public boolean onTouch(View view, MotionEvent event) {
    switch ( event.getAction() ){

        case MotionEvent.ACTION_DOWN:{
            x1 = event.getX();
            y1 = event.getY();
            break;
        }

        case MotionEvent.ACTION_UP:{
            x2 = event.getX();
            y2 = event.getY();

            if ( x1<x2 ) {
                //implement what you need to do here
            }
            if ( x1>x2 ) {
                //implement what you need to do here
            }
            break;
        }
    }
    return false;
}
person Ashana.Jackol    schedule 21.11.2014
comment
Ответ не дает логики переброски, которую ищет OP. - person Sipty; 27.07.2015