Saya ingin mendapatkan melemparkan
gerakan deteksi bekerja di aplikasi Android.
Apa yang saya miliki adalah GridLayout
yang berisi 9 `ImageView ini. Sumber dapat ditemukan di sini: [Romain Orang's Grid Layout][4].
File yang saya ambil adalah dari Romain Guy's Photostream aplikasi dan hanya sedikit disesuaikan.
Untuk sederhana klik situasi saya hanya perlu mengatur onClickListener
untuk setiap ImageView
saya tambahkan untuk menjadi yang utama aktivitas
yang mengimplementasikan Melihat.OnClickListener
. Tampaknya jauh lebih rumit untuk melaksanakan sesuatu yang mengakui melemparkan
. Saya kira ini adalah karena dapat span views
?
OnGestureListener
I don't tahu bagaimana untuk
menetapkan itu sebagai sikap pendengar untuk
the Grid
atau Gambar
pandangan bahwa saya
tambahkan.public class SelectFilterActivity meluas Aktivitas mengimplementasikan Lihat.OnClickListener, OnGestureListener { ...
OnTouchListener
maka saya tidak memiliki
onFling
metode menimpa
(memiliki
dua peristiwa sebagai parameter yang memungkinkan saya
untuk menentukan apakah fling adalah
perlu diperhatikan).public class SelectFilterActivity meluas Aktivitas mengimplementasikan Lihat.OnClickListener, OnTouchListener { ...
View
, seperti GestureImageView
yang meluas ImageView
I don't tahu bagaimana untuk memberitahu aktivitas yang melemparkan
telah terjadi dari pandangan. Dalam hal apapun, saya mencoba ini dan metode yang tidak't disebut ketika aku menyentuh layar.Aku benar-benar hanya butuh contoh konkret dari kerja ini seluruh pandangan. Apa, kapan dan bagaimana saya harus melampirkan pendengar
? Aku harus mampu untuk mendeteksi klik tunggal juga.
// Gesture detection
mGestureDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int dx = (int) (e2.getX() - e1.getX());
// don't accept the fling if it's too short
// as it may conflict with a button push
if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.absvelocityY)) {
if (velocityX > 0) {
moveRight();
} else {
moveLeft();
}
return true;
} else {
return false;
}
}
});
Apakah mungkin untuk meletakkan transparan pemandangan dari atas layar saya untuk menangkap teman kencan?
Jika saya memilih untuk tidak mengembang
saya anak gambar pemandangan dari XML saya bisa lulus GestureDetector
sebagai parameter konstruktor baru subclass dari ImageView
yang saya buat?
Ini adalah sangat sederhana kegiatan yang saya'm mencoba untuk mendapatkan melemparkan
deteksi untuk bekerja untuk: SelectFilterActivity (Diadaptasi dari photostream).
I've telah mencari sumber-sumber ini:
Tidak ada yang bekerja untuk saya sejauh ini dan saya berharap untuk beberapa petunjuk.
Terima kasih untuk Kode Shogun, dan kode saya disesuaikan dengan situasi saya.
Biarkan aktivitas anda menerapkanOnClickListener
seperti biasa:
public class SelectFilterActivity extends Activity implements OnClickListener {
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
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* ... */
// Gesture detection
gestureDetector = new GestureDetector(this, new MyGestureDetector());
gestureListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
};
}
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(SelectFilterActivity.this, "Left Swipe", Toast.LENGTH_SHORT).show();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Toast.makeText(SelectFilterActivity.this, "Right Swipe", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// nothing
}
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
}
}
Melampirkan sikap pendengar untuk semua pandangan anda menambah utama tata letak;
// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this);
imageView.setOnTouchListener(gestureListener);
Watch kagum saat anda ditimpa metode memukul, kedua onClick(View v)
dari aktivitas dan onFling
dari sikap pendengar.
public void onClick(View v) {
Filter f = (Filter) v.getTag();
FilterFullscreenActivity.show(this, input, f);
}
The post 'melemparkan' tari adalah opsional, tetapi dianjurkan.
Salah satu dari jawaban di atas menyebutkan penanganan kepadatan pixel yang berbeda tetapi menunjukkan komputasi menggesek parameter dengan tangan. Perlu dicatat bahwa anda dapat benar-benar memperoleh skala, nilai-nilai yang wajar dari sistem yang menggunakan ViewConfiguration
kelas:
final ViewConfiguration vc = ViewConfiguration.get(getContext());
final int swipeMinDistance = vc.getScaledPagingTouchSlop();
final int swipeThresholdVelocity = vc.getScaledMinimumFlingVelocity();
final int swipeMaxOffPath = vc.getScaledTouchSlop();
// (there is also vc.getScaledMaximumFlingVelocity() one could check against)
Saya melihat bahwa menggunakan nilai-nilai ini menyebabkan "merasa" dari hubungan asmara menjadi lebih konsisten antara aplikasi dan sisa sistem.
Saya melakukannya sedikit berbeda, dan menulis sebuah tambahan detektor kelas yang mengimplementasikan Melihat.onTouchListener
`onCreate syi'ah hanya menambahkannya ke level terendah tata letak seperti ini:
ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
lowestLayout = (RelativeLayout)this.findViewById(R.id.lowestLayout);
lowestLayout.setOnTouchListener(activitySwipeDetector);
mana id.lowestLayout adalah id.xxx untuk melihat terendah dalam hirarki tata letak dan lowestLayout dinyatakan sebagai RelativeLayout
Dan kemudian ada kegiatan yang sebenarnya menggesek detektor kelas:
public class ActivitySwipeDetector implements View.OnTouchListener {
static final String logTag = "ActivitySwipeDetector";
private Activity activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
public ActivitySwipeDetector(Activity activity){
this.activity = activity;
}
public void onRightSwipe(){
Log.i(logTag, "RightToLeftSwipe!");
activity.doSomething();
}
public void onLeftSwipe(){
Log.i(logTag, "LeftToRightSwipe!");
activity.doSomething();
}
public void onDownSwipe(){
Log.i(logTag, "onTopToBottomSwipe!");
activity.doSomething();
}
public void onUpSwipe(){
Log.i(logTag, "onBottomToTopSwipe!");
activity.doSomething();
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// swipe horizontal?
if(Math.abs(deltaX) > Math.abs(deltaY))
{
if(Math.abs(deltaX) > MIN_DISTANCE){
// left or right
if(deltaX > 0) { this.onRightSwipe(); return true; }
if(deltaX < 0) { this.onLeftSwipe(); return true; }
}
else {
Log.i(logTag, "Horizontal Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
return false; // We don't consume the event
}
}
// swipe vertical?
else
{
if(Math.abs(deltaY) > MIN_DISTANCE){
// top or down
if(deltaY < 0) { this.onDownSwipe(); return true; }
if(deltaY > 0) { this.onUpSwipe(); return true; }
}
else {
Log.i(logTag, "Vertical Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
return false; // We don't consume the event
}
}
return true;
}
}
return false;
}
}
Bekerja benar-benar baik untuk saya!
Aku sedikit dimodifikasi dan diperbaiki solusi dari Thomas Fankhauser
Seluruh sistem terdiri dari dua file, SwipeInterface dan ActivitySwipeDetector
SwipeInterface.java
import android.view.View;
public interface SwipeInterface {
public void bottom2top(View v);
public void left2right(View v);
public void right2left(View v);
public void top2bottom(View v);
}
Detektor
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class ActivitySwipeDetector implements View.OnTouchListener {
static final String logTag = "ActivitySwipeDetector";
private SwipeInterface activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
public ActivitySwipeDetector(SwipeInterface activity){
this.activity = activity;
}
public void onRightToLeftSwipe(View v){
Log.i(logTag, "RightToLeftSwipe!");
activity.right2left(v);
}
public void onLeftToRightSwipe(View v){
Log.i(logTag, "LeftToRightSwipe!");
activity.left2right(v);
}
public void onTopToBottomSwipe(View v){
Log.i(logTag, "onTopToBottomSwipe!");
activity.top2bottom(v);
}
public void onBottomToTopSwipe(View v){
Log.i(logTag, "onBottomToTopSwipe!");
activity.bottom2top(v);
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// swipe horizontal?
if(Math.abs(deltaX) > MIN_DISTANCE){
// left or right
if(deltaX < 0) { this.onLeftToRightSwipe(v); return true; }
if(deltaX > 0) { this.onRightToLeftSwipe(v); return true; }
}
else {
Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
}
// swipe vertical?
if(Math.abs(deltaY) > MIN_DISTANCE){
// top or down
if(deltaY < 0) { this.onTopToBottomSwipe(v); return true; }
if(deltaY > 0) { this.onBottomToTopSwipe(v); return true; }
}
else {
Log.i(logTag, "Swipe was only " + Math.abs(deltaX) + " long, need at least " + MIN_DISTANCE);
v.performClick();
}
}
}
return false;
}
}
hal ini digunakan seperti ini:
ActivitySwipeDetector swipe = new ActivitySwipeDetector(this);
LinearLayout swipe_layout = (LinearLayout) findViewById(R.id.swipe_layout);
swipe_layout.setOnTouchListener(swipe);
Dan dalam melaksanakan Aktivitas
yang anda butuhkan untuk menerapkan metode dari SwipeInterface, dan anda dapat mengetahui pada yang Melihat Menggesek Acara disebut.
@Override
public void left2right(View v) {
switch(v.getId()){
case R.id.swipe_layout:
// do your stuff here
break;
}
}
Gerakan menggesek detektor kode di atas adalah sangat berguna! Namun anda dapat berharap untuk membuat ini solusi kepadatan agnostik dengan menggunakan berikut nilai-nilai relatif (REL_SWIPE)
daripada nilai absolut (SWIPE_)
DisplayMetrics dm = getResources().getDisplayMetrics();
int REL_SWIPE_MIN_DISTANCE = (int)(SWIPE_MIN_DISTANCE * dm.densityDpi / 160.0f);
int REL_SWIPE_MAX_OFF_PATH = (int)(SWIPE_MAX_OFF_PATH * dm.densityDpi / 160.0f);
int REL_SWIPE_THRESHOLD_VELOCITY = (int)(SWIPE_THRESHOLD_VELOCITY * dm.densityDpi / 160.0f);
Versi saya solusi yang diusulkan oleh Thomas Fankhauser dan Marek Sebera (tidak menangani gesekan vertikal):
SwipeInterface.java
import android.view.View;
public interface SwipeInterface {
public void onLeftToRight(View v);
public void onRightToLeft(View v);
}
ActivitySwipeDetector.java
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public class ActivitySwipeDetector implements View.OnTouchListener {
static final String logTag = "ActivitySwipeDetector";
private SwipeInterface activity;
private float downX, downY;
private long timeDown;
private final float MIN_DISTANCE;
private final int VELOCITY;
private final float MAX_OFF_PATH;
public ActivitySwipeDetector(Context context, SwipeInterface activity){
this.activity = activity;
final ViewConfiguration vc = ViewConfiguration.get(context);
DisplayMetrics dm = context.getResources().getDisplayMetrics();
MIN_DISTANCE = vc.getScaledPagingTouchSlop() * dm.density;
VELOCITY = vc.getScaledMinimumFlingVelocity();
MAX_OFF_PATH = MIN_DISTANCE * 2;
}
public void onRightToLeftSwipe(View v){
Log.i(logTag, "RightToLeftSwipe!");
activity.onRightToLeft(v);
}
public void onLeftToRightSwipe(View v){
Log.i(logTag, "LeftToRightSwipe!");
activity.onLeftToRight(v);
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
Log.d("onTouch", "ACTION_DOWN");
timeDown = System.currentTimeMillis();
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
Log.d("onTouch", "ACTION_UP");
long timeUp = System.currentTimeMillis();
float upX = event.getX();
float upY = event.getY();
float deltaX = downX - upX;
float absDeltaX = Math.abs(deltaX);
float deltaY = downY - upY;
float absDeltaY = Math.abs(deltaY);
long time = timeUp - timeDown;
if (absDeltaY > MAX_OFF_PATH) {
Log.i(logTag, String.format("absDeltaY=%.2f, MAX_OFF_PATH=%.2f", absDeltaY, MAX_OFF_PATH));
return v.performClick();
}
final long M_SEC = 1000;
if (absDeltaX > MIN_DISTANCE && absDeltaX > time * VELOCITY / M_SEC) {
if(deltaX < 0) { this.onLeftToRightSwipe(v); return true; }
if(deltaX > 0) { this.onRightToLeftSwipe(v); return true; }
} else {
Log.i(logTag, String.format("absDeltaX=%.2f, MIN_DISTANCE=%.2f, absDeltaX > MIN_DISTANCE=%b", absDeltaX, MIN_DISTANCE, (absDeltaX > MIN_DISTANCE)));
Log.i(logTag, String.format("absDeltaX=%.2f, time=%d, VELOCITY=%d, time*VELOCITY/M_SEC=%d, absDeltaX > time * VELOCITY / M_SEC=%b", absDeltaX, time, VELOCITY, time * VELOCITY / M_SEC, (absDeltaX > time * VELOCITY / M_SEC)));
}
}
}
return false;
}
}
Pertanyaan ini adalah jenis dari lama dan pada bulan juli 2011 Google merilis Kompatibilitas Paket, revisi 3) yang termasuk ViewPager
yang bekerja dengan Android 1.6 ke atas. The GestureListener
jawaban yang diposting untuk pertanyaan ini don't merasa sangat elegan di Android. Jika anda'kembali mencari kode yang digunakan dalam beralih di antara foto-foto di Galeri Android atau beralih pandangan dalam Bermain baru Pasar aplikasi maka's pasti ViewPager
.
Berikut's beberapa link untuk info lebih lanjut:
Ada's beberapa proposisi melalui web (dan halaman ini) untuk menggunakan ViewConfiguration.getScaledTouchSlop() untuk memiliki perangkat skala nilai untuk SWIPE_MIN_DISTANCE
.
getScaledTouchSlop()
ini dimaksudkan untuk "bergulir ambang" jarak, tidak menggesek. Bergulir ambang batas jarak harus lebih kecil dari "ayunan antara halaman" ambang batas jarak. Sebagai contoh, fungsi ini mengembalikan 12 piksel pada saya Samsung GS2, dan contoh-contoh yang dikutip di halaman ini adalah sekitar 100 piksel.
Dengan API Level 8 (Android 2.2, Froyo), anda've got getScaledPagingTouchSlop()
, yang ditujukan untuk halaman menggesek.
Pada perangkat saya, itu kembali 24 (piksel). Jadi jika anda're pada API Level < 8, aku berpikir "2 * getScaledTouchSlop()
" harus "s" geser ke ambang batas.
Tapi pengguna aplikasi saya dengan layar kecil mengatakan kepada saya bahwa itu terlalu sedikit... Seperti pada aplikasi saya, anda dapat menggulir secara vertikal, dan mengubah halaman secara horizontal. Dengan usulan nilai, mereka kadang-kadang mengubah halaman bukannya bergulir.
Juga sebagai peningkatan kecil.
Alasan utama untuk try/catch blok adalah bahwa e1 bisa menjadi null untuk awal gerakan. selain try/catch, termasuk tes untuk batal dan kembali. mirip dengan berikut ini
if (e1 == null || e2 == null) return false;
try {
...
} catch (Exception e) {}
return false;
Ada banyak informasi yang sangat baik di sini. Sayangnya banyak berselingkuh-kode pengolahan yang tersebar di berbagai situs di berbagai negara penyelesaian, meskipun orang akan berpikir ini adalah penting untuk banyak aplikasi.
I've mengambil waktu untuk membuat melemparkan pendengar yang memverifikasi bahwa sesuai kondisi terpenuhi. I've menambahkan halaman melemparkan pendengar yang menambahkan lebih banyak pemeriksaan untuk memastikan bahwa teman kencan memenuhi ambang batas untuk halaman teman kencan. Kedua pendengar memungkinkan anda untuk dengan mudah membatasi teman kencan ke horisontal atau sumbu vertikal. Anda dapat melihat bagaimana hal itu's digunakan dalam lihat untuk geser gambar. Saya mengakui bahwa orang-orang di sini telah melakukan sebagian besar penelitian---I've hanya menempatkan bersama-sama ke yang dapat digunakan perpustakaan.
Beberapa hari terakhir ini mewakili menusuk pertama saya di coding di Android; berharap lebih yang akan datang.
Ini adalah gabungan menjawab dua jawaban di atas, jika ada yang ingin kerja pelaksanaan.
package com.yourapplication;
import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public abstract class OnSwipeListener implements View.OnTouchListener {
private final GestureDetector gestureDetector;
public OnSwipeListener(Context context){
gestureDetector = new GestureDetector(context, new OnSwipeGestureListener(context));
gestureDetector.setIsLongpressEnabled(false);
}
@Override
public boolean onTouch(View view, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
private final class OnSwipeGestureListener extends GestureDetector.SimpleOnGestureListener {
private final int minSwipeDelta;
private final int minSwipeVelocity;
private final int maxSwipeVelocity;
private OnSwipeGestureListener(Context context) {
ViewConfiguration configuration = ViewConfiguration.get(context);
// We think a swipe scrolls a full page.
//minSwipeDelta = configuration.getScaledTouchSlop();
minSwipeDelta = configuration.getScaledPagingTouchSlop();
minSwipeVelocity = configuration.getScaledMinimumFlingVelocity();
maxSwipeVelocity = configuration.getScaledMaximumFlingVelocity();
}
@Override
public boolean onDown(MotionEvent event) {
// Return true because we want system to report subsequent events to us.
return true;
}
// NOTE: see http://stackoverflow.com/questions/937313/android-basic-gesture-detection
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX,
float velocityY) {
boolean result = false;
try {
float deltaX = event2.getX() - event1.getX();
float deltaY = event2.getY() - event1.getY();
float absVelocityX = Math.abs(velocityX);
float absVelocityY = Math.abs(velocityY);
float absDeltaX = Math.abs(deltaX);
float absDeltaY = Math.abs(deltaY);
if (absDeltaX > absDeltaY) {
if (absDeltaX > minSwipeDelta && absVelocityX > minSwipeVelocity
&& absVelocityX < maxSwipeVelocity) {
if (deltaX < 0) {
onSwipeLeft();
} else {
onSwipeRight();
}
}
result = true;
} else if (absDeltaY > minSwipeDelta && absVelocityY > minSwipeVelocity
&& absVelocityY < maxSwipeVelocity) {
if (deltaY < 0) {
onSwipeTop();
} else {
onSwipeBottom();
}
}
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
public void onSwipeLeft() {}
public void onSwipeRight() {}
public void onSwipeTop() {}
public void onSwipeBottom() {}
}
Anda dapat menggunakan droidQuery perpustakaan untuk menangani teman kencan, klik, klik panjang, dan acara-acara adat. Pelaksanaan dibangun pada jawaban saya sebelumnya di bawah ini, tapi droidQuery menyediakan licin, sederhana sintaks:
//global variables private boolean isSwiping = false;
private SwipeDetector.Direction swipeDirection = null;
private View v;//must be instantiated before next call.
//swipe-handling code
$.with(v).swipe(new Function() {
@Override
public void invoke($ droidQuery, Object... params) {
if (params[0] == SwipeDetector.Direction.START)
isSwiping = true;
else if (params[0] == SwipeDetector.Direction.STOP) {
if (isSwiping) { isSwiping = false;
if (swipeDirection != null) {
switch(swipeDirection) {
case DOWN : //TODO: Down swipe complete, so do something
break;
case UP :
//TODO: Up swipe complete, so do something
break;
case LEFT :
//TODO: Left swipe complete, so do something
break;
case RIGHT :
//TODO: Right swipe complete, so do something
break;
default : break;
}
} }
}
else {
swipeDirection = (SwipeDetector.Direction) params[0];
}
}
});
Jawaban ini menggunakan kombinasi dari komponen-komponen dari jawaban yang lain di sini. Ini terdiri dari SwipeDetector
kelas, yang telah batin antarmuka untuk mendengarkan acara. Saya juga memberikan RelativeLayout
untuk menunjukkan bagaimana untuk menimpa sebuah Melihat
's onTouch
metode untuk memungkinkan kedua menggesek peristiwa dan lain terdeteksi peristiwa (seperti klik atau klik panjang).
SwipeDetector
package self.philbrown;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
/**
* Detect Swipes on a per-view basis. Based on original code by Thomas Fankhauser on StackOverflow.com,
* with adaptations by other authors (see link).
* @author Phil Brown
* @see <a href="http://stackoverflow.com/questions/937313/android-basic-gesture-detection">android-basic-gesture-detection</a>
*/
public class SwipeDetector implements View.OnTouchListener
{
/**
* The minimum distance a finger must travel in order to register a swipe event.
*/
private int minSwipeDistance;
/** Maintains a reference to the first detected down touch event. */
private float downX, downY;
/** Maintains a reference to the first detected up touch event. */
private float upX, upY;
/** provides access to size and dimension contants */
private ViewConfiguration config;
/**
* provides callbacks to a listener class for various swipe gestures.
*/
private SwipeListener listener;
public SwipeDetector(SwipeListener listener)
{
this.listener = listener;
}
/**
* {@inheritDoc}
*/
public boolean onTouch(View v, MotionEvent event)
{
if (config == null)
{
config = ViewConfiguration.get(v.getContext());
minSwipeDistance = config.getScaledTouchSlop();
}
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
return true;
case MotionEvent.ACTION_UP:
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// swipe horizontal?
if(Math.abs(deltaX) > minSwipeDistance)
{
// left or right
if (deltaX < 0)
{
if (listener != null)
{
listener.onRightSwipe(v);
return true;
}
}
if (deltaX > 0)
{
if (listener != null)
{
listener.onLeftSwipe(v);
return true;
}
}
}
// swipe vertical?
if(Math.abs(deltaY) > minSwipeDistance)
{
// top or down
if (deltaY < 0)
{
if (listener != null)
{
listener.onDownSwipe(v);
return true;
}
}
if (deltaY > 0)
{
if (listener != null)
{
listener.onUpSwipe(v);
return true;
}
}
}
}
return false;
}
/**
* Provides callbacks to a registered listener for swipe events in {@link SwipeDetector}
* @author Phil Brown
*/
public interface SwipeListener
{
/** Callback for registering a new swipe motion from the bottom of the view toward its top. */
public void onUpSwipe(View v);
/** Callback for registering a new swipe motion from the left of the view toward its right. */
public void onRightSwipe(View v);
/** Callback for registering a new swipe motion from the right of the view toward its left. */
public void onLeftSwipe(View v);
/** Callback for registering a new swipe motion from the top of the view toward its bottom. */
public void onDownSwipe(View v);
}
}
Menggesek Interceptor Lihat
package self.philbrown;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
import com.npeinc.module_NPECore.model.SwipeDetector;
import com.npeinc.module_NPECore.model.SwipeDetector.SwipeListener;
/**
* View subclass used for handling all touches (swipes and others)
* @author Phil Brown
*/
public class SwipeInterceptorView extends RelativeLayout
{
private SwipeDetector swiper = null;
public void setSwipeListener(SwipeListener listener)
{
if (swiper == null)
swiper = new SwipeDetector(listener);
}
public SwipeInterceptorView(Context context) {
super(context);
}
public SwipeInterceptorView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SwipeInterceptorView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent e)
{
boolean swipe = false, touch = false;
if (swiper != null)
swipe = swiper.onTouch(this, e);
touch = super.onTouchEvent(e);
return swipe || touch;
}
}
Aku tahu itu terlambat untuk menjawab tapi Tetap saya posting Menggesek Deteksi untuk ListView Bagaimana untuk menggunakan Geser Touch Pendengar di ListView Item.
Refrence: Exterminator13(salah satu dari jawaban di halaman ini)
Membuat satu ActivitySwipeDetector.class
package com.example.wocketapp;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public class ActivitySwipeDetector implements View.OnTouchListener
{
static final String logTag = "SwipeDetector";
private SwipeInterface activity;
private float downX, downY;
private long timeDown;
private final float MIN_DISTANCE;
private final int VELOCITY;
private final float MAX_OFF_PATH;
public ActivitySwipeDetector(Context context, SwipeInterface activity)
{
this.activity = activity;
final ViewConfiguration vc = ViewConfiguration.get(context);
DisplayMetrics dm = context.getResources().getDisplayMetrics();
MIN_DISTANCE = vc.getScaledPagingTouchSlop() * dm.density;
VELOCITY = vc.getScaledMinimumFlingVelocity();
MAX_OFF_PATH = MIN_DISTANCE * 2;
}
public void onRightToLeftSwipe(View v)
{
Log.i(logTag, "RightToLeftSwipe!");
activity.onRightToLeft(v);
}
public void onLeftToRightSwipe(View v)
{
Log.i(logTag, "LeftToRightSwipe!");
activity.onLeftToRight(v);
}
public boolean onTouch(View v, MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
Log.d("onTouch", "ACTION_DOWN");
timeDown = System.currentTimeMillis();
downX = event.getX();
downY = event.getY();
v.getParent().requestDisallowInterceptTouchEvent(false);
return true;
}
case MotionEvent.ACTION_MOVE:
{
float y_up = event.getY();
float deltaY = y_up - downY;
float absDeltaYMove = Math.abs(deltaY);
if (absDeltaYMove > 60)
{
v.getParent().requestDisallowInterceptTouchEvent(false);
}
else
{
v.getParent().requestDisallowInterceptTouchEvent(true);
}
}
break;
case MotionEvent.ACTION_UP:
{
Log.d("onTouch", "ACTION_UP");
long timeUp = System.currentTimeMillis();
float upX = event.getX();
float upY = event.getY();
float deltaX = downX - upX;
float absDeltaX = Math.abs(deltaX);
float deltaY = downY - upY;
float absDeltaY = Math.abs(deltaY);
long time = timeUp - timeDown;
if (absDeltaY > MAX_OFF_PATH)
{
Log.e(logTag, String.format(
"absDeltaY=%.2f, MAX_OFF_PATH=%.2f", absDeltaY,
MAX_OFF_PATH));
return v.performClick();
}
final long M_SEC = 1000;
if (absDeltaX > MIN_DISTANCE && absDeltaX > time * VELOCITY / M_SEC)
{
v.getParent().requestDisallowInterceptTouchEvent(true);
if (deltaX < 0)
{
this.onLeftToRightSwipe(v);
return true;
}
if (deltaX > 0)
{
this.onRightToLeftSwipe(v);
return true;
}
}
else
{
Log.i(logTag,
String.format(
"absDeltaX=%.2f, MIN_DISTANCE=%.2f, absDeltaX > MIN_DISTANCE=%b",
absDeltaX, MIN_DISTANCE,
(absDeltaX > MIN_DISTANCE)));
Log.i(logTag,
String.format(
"absDeltaX=%.2f, time=%d, VELOCITY=%d, time*VELOCITY/M_SEC=%d, absDeltaX > time * VELOCITY / M_SEC=%b",
absDeltaX, time, VELOCITY, time * VELOCITY
/ M_SEC, (absDeltaX > time * VELOCITY
/ M_SEC)));
}
v.getParent().requestDisallowInterceptTouchEvent(false);
}
}
return false;
}
public interface SwipeInterface
{
public void onLeftToRight(View v);
public void onRightToLeft(View v);
}
}
Panggilan dari aktivitas kelas seperti ini:
yourLayout.setOnTouchListener(new ActivitySwipeDetector(this, your_activity.this));
Dan Don't lupa untuk melaksanakan SwipeInterface yang akan memberikan anda dua @override metode:
@Override
public void onLeftToRight(View v)
{
Log.e("TAG", "L to R");
}
@Override
public void onRightToLeft(View v)
{
Log.e("TAG", "R to L");
}
Jika anda tidak suka untuk membuat sebuah kelas terpisah atau membuat kode yang kompleks,
Anda hanya dapat membuat GestureDetector variabel dalam OnTouchListener dan membuat kode anda lebih mudah
namVyuVar dapat berupa nama Tampilan di mana anda perlu untuk mengatur listner
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;
}
});
});
Gerakan yang halus gerakan untuk memicu interaksi antara layar sentuh dan pengguna. Hal ini berlangsung untuk waktu antara pertama menyentuh pada layar untuk titik ketika terakhir jari permukaan daun.
Android menyediakan kami dengan kelas yang disebut GestureDetector menggunakan yang kita dapat mendeteksi gerakan umum seperti menekan ke bawah dan ke atas, menggesekkan vertikal dan horizontal (fling), panjang dan pendek pers, double pdam, dll. dan melampirkan pendengar untuk mereka.
Membuat Aktivitas kita kelas melaksanakan GestureDetector.OnDoubleTapListener (untuk double tap gesture detection) dan GestureDetector.OnGestureListener interface dan menerapkan semua metode abstrak.Untuk info lebih lanjut. anda dapat mengunjungi https://developer.android.com/training/gestures/detector.html . Sopan
Untuk Demo Test.GestureDetectorDemo
Saya nedded yang lebih generik Kelas , aku mengambil Tomas's class dan menambahkan sebuah Interface yang mengirimkan acara untuk Kegiatan atau Fragmen. itu akan mendaftarkan pendengar pada konstruktor jadi pastikan anda menerapkan antarmuka atau ClassCastException akan thorwn. antarmuka kembali salah satu dari empat final int didefinisikan di hotel ini dan akan kembali melihat di mana itu akan aktif pada.
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SwipeDetector implements View.OnTouchListener{
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
public final static int RIGHT_TO_LEFT=1;
public final static int LEFT_TO_RIGHT=2;
public final static int TOP_TO_BOTTOM=3;
public final static int BOTTOM_TO_TOP=4;
private View v;
private onSwipeEvent swipeEventListener;
public SwipeDetector(Activity activity,View v){
try{
swipeEventListener=(onSwipeEvent)activity;
}
catch(ClassCastException e)
{
Log.e("ClassCastException",activity.toString()+" must implement SwipeDetector.onSwipeEvent");
}
this.v=v;
}
public SwipeDetector(Fragment fragment,View v){
try{
swipeEventListener=(onSwipeEvent)fragment;
}
catch(ClassCastException e)
{
Log.e("ClassCastException",fragment.toString()+" must implement SwipeDetector.onSwipeEvent");
}
this.v=v;
}
public void onRightToLeftSwipe(){
swipeEventListener.SwipeEventDetected(v,RIGHT_TO_LEFT);
}
public void onLeftToRightSwipe(){
swipeEventListener.SwipeEventDetected(v,LEFT_TO_RIGHT);
}
public void onTopToBottomSwipe(){
swipeEventListener.SwipeEventDetected(v,TOP_TO_BOTTOM);
}
public void onBottomToTopSwipe(){
swipeEventListener.SwipeEventDetected(v,BOTTOM_TO_TOP);
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
//HORIZONTAL SCROLL
if(Math.abs(deltaX) > Math.abs(deltaY))
{
if(Math.abs(deltaX) > MIN_DISTANCE){
// left or right
if(deltaX < 0)
{
this.onLeftToRightSwipe();
return true;
}
if(deltaX > 0) {
this.onRightToLeftSwipe();
return true;
}
}
else {
//not long enough swipe...
return false;
}
}
//VERTICAL SCROLL
else
{
if(Math.abs(deltaY) > MIN_DISTANCE){
// top or down
if(deltaY < 0)
{ this.onTopToBottomSwipe();
return true;
}
if(deltaY > 0)
{ this.onBottomToTopSwipe();
return true;
}
}
else {
//not long enough swipe...
return false;
}
}
return true;
}
}
return false;
}
public interface onSwipeEvent
{
public void SwipeEventDetected(View v , int SwipeType);
}
}