Vreau să te arunca
gest de detectare lucru în cererea mea Android.
Ceea ce am este un GridLayout, care conține 9
ImageView lui. Sursa poate fi găsit aici: [Romain Voi's Grid Layout][4].
Că fișierul este de Romain Guy's Photostream cerere și a fost doar ușor adaptat.
Pentru simplu click situație trebuie doar să setați onClickListener pentru fiecare
ImageViewadaug a fi principala "activitate" care pune în aplicare Viziunea.OnClickListener
. Se pare infinit mai complicat să pună în aplicare ceva care recunoaște o aventură
. Presupun că acest lucru este pentru că ea poate span vizualizări
?
OnGestureListener
eu nu't știu cum să
setați ca gestul ascultător pentru
pe "Grilă" sau "Imagine" vedere că am
adauga.public class SelectFilterActivity extinde Activitatea implementează Vedere.OnClickListener, OnGestureListener { ...
OnTouchListener
atunci nu am
onFling
metoda prototipul
(are
două evenimente ca parametri permițându-mi
pentru a determina dacă aventura a fost
de remarcat).public class SelectFilterActivity extinde Activitatea implementează Vedere.OnClickListener, OnTouchListener { ...
GestureImageView
care se extinde ImageView
eu nu't știu cum să-i spuneți activitatea pe care o aventură
a avut loc la vedere. În orice caz, am încercat acest lucru și metode au fost't sunat când am atins ecranul.Chiar am nevoie doar de un exemplu concret de acest lucru peste vedere. Ce, când și cum ar trebui să atașați acest ascultator
? Am nevoie pentru a fi capabil de a detecta un singur clic, de asemenea,.
// 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;
}
}
});
Este posibil să se stabilească o imagine transparentă de-a lungul partea de sus a ecranului pentru a captura aventuri?
Dacă am alege să nu umfla
copilul meu imaginii vedere de la XML pot trece GestureDetector
ca parametru constructorului la o nouă subclasă de `ImageView că am crea?
Acest lucru este foarte simplu, activitate care nu'm încercat să te arunca
de detectare a lucra pentru: SelectFilterActivity (Adaptat din photostream).
Am'am fost în căutarea la aceste surse:
Nimic nu a lucrat pentru mine până acum și am fost în speranța pentru unele indicii.
Datorită Cod Shogun, al carui cod l-am adaptat la situația mea.
Lasa-ti activitatea pună în aplicareOnClickListener
ca de obicei:
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;
}
}
}
Atașați gestul tău ascultător de toate opiniile pe care le adăugați la aspectul principal;
// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this);
imageView.setOnTouchListener(gestureListener);
Urmăriți în venerație ca înlocuită de metode sunt lovit, atât onClick(Vezi v)
de activitate și onFling
de gestul ascultător.
public void onClick(View v) {
Filter f = (Filter) v.getTag();
FilterFullscreenActivity.show(this, input, f);
}
Post 'arunca' dansul este opțională, dar a încurajat.
Unul dintre răspunsurile de mai sus menționează manipulare diferite densitate a pixelilor, dar sugerează de calcul bețivan parametrii de mână. Este de remarcat faptul că puteți obține de fapt scalate, valori rezonabile din sistem folosind ViewConfiguration
clasa:
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)
Am observat că, folosind aceste valori determină "simt" de aventura pentru a fi mai coerentă între cererea și restul sistemului.
Eu o fac un pic diferit, și a scris un plus de detector de clasă care implementează punctul de Vedere.onTouchListener`
`onCreate ' is pur și simplu adăugați-l la cel mai mic aspect astfel:
ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
lowestLayout = (RelativeLayout)this.findViewById(R.id.lowestLayout);
lowestLayout.setOnTouchListener(activitySwipeDetector);
în cazul în care id-ul.lowestLayout este id-ul.xxx pentru a putea vizualiza cel mai mic în ierarhia de dispunere și lowestLayout este declarat ca un RelativeLayout
Și apoi, nu este efectiv activitatea treceți detector de clasa:
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;
}
}
Funcționează foarte bine pentru mine!
Am modificat si reparat soluție de Thomas Fankhauser
Întregul sistem este format din două fișiere, SwipeInterface și 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);
}
Detector
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;
}
}
acesta este utilizat astfel:
ActivitySwipeDetector swipe = new ActivitySwipeDetector(this);
LinearLayout swipe_layout = (LinearLayout) findViewById(R.id.swipe_layout);
swipe_layout.setOnTouchListener(swipe);
Și în punerea în aplicare a "Activitate" trebuie să pună în aplicare metode de SwipeInterface, și puteți afla de pe care Vezi Treceți Eveniment a fost numit.
@Override
public void left2right(View v) {
switch(v.getId()){
case R.id.swipe_layout:
// do your stuff here
break;
}
}
Bețivan gest detector de cod de mai sus este foarte util! Poate cu toate acestea doresc să facă această soluție densitate agnostic utilizând următoarele valori relative (REL_SWIPE)
, mai degrabă decât valori absolute (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);
Versiunea mea de soluția propusă de Thomas Fankhauser și Marek Sebera (nu mâner vertical swipes):
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;
}
}
Această întrebare este la fel de vechi și, în iulie 2011, Google a lansat de Compatibilitate Pachet, revizia 3), care include ViewPager care functioneaza cu Android 1.6 în sus. Anii
GestureListener răspunsurile postate pentru această întrebare nu't simt foarte elegant pe Android. Daca're în căutarea pentru codul folosit în comutarea între fotografii în Galerie Android sau trecerea de vedere în noul Joc app Piață de atunci's cu siguranta ViewPager
.
Aici's niste link-uri pentru mai multe informații:
Nu's o propunere pe web (și această pagină) pentru a utiliza ViewConfiguration.getScaledTouchSlop() să aibă un dispozitiv scalate valoare pentru SWIPE_MIN_DISTANCE
.
getScaledTouchSlop()
este destinat pentru "defilare prag" de la distanță, nu treceți. Defilare distanța de prag trebuie să fie mai mic decât un "leagăn între pagina" distanța de prag. De exemplu, această funcție returnează 12 pixeli pe Samsung GS2, și exemplele citate în această pagină sunt în jur de 100 de pixeli.
Cu API de Nivel 8 (Android 2.2, Froyo), nu'am getScaledPagingTouchSlop()
, destinat pentru pagina bețivan.
Pe aparatul meu, întoarce-24 (pixeli). Deci, dacă te're la Nivel de API < 8, cred ca "2 * getScaledTouchSlop()
" ar trebui să fie "standard" treceți pragul.
Dar utilizatorii de cererea mea cu ecrane mici mi-a spus că a fost prea puțini... Ca pe cererea mea, puteți defila pe verticală, și de a schimba pagina orizontal. Cu propunerea de valoare, au, uneori, schimba pagina în loc de defilare.
De asemenea, ca un accesoriu minor.
Principalul motiv pentru blocul try/catch este că e1 ar putea fi nul pentru deplasare inițială. în plus față de try/catch, include un test pentru nul și să se întoarcă. similar cu următorul
if (e1 == null || e2 == null) return false;
try {
...
} catch (Exception e) {}
return false;
Există o mulțime de informații excelent aici. Din păcate, o mulțime de această aventură-cod de prelucrare este împrăștiate în jurul valorii de pe diverse site-uri în diferite stadii de finalizare, chiar dacă unul ar fi că acest lucru este esențial pentru multe aplicații.
Am'am luat timp pentru a crea un arunca ascultător, care verifică dacă condițiile necesare sunt îndeplinite. Am'am adăugat un pagina arunca ascultător, care adaugă mai multe controale pentru a se asigura că aruncă atinge pragul pentru pagina de aventuri. Ambele aceste ascultători vă permit să restricționeze cu ușurință aruncă la axă orizontală sau verticală. Puteți vedea cum se's a folosit într-un vezi pentru alunecare imagini. Recunosc faptul că oamenii de aici au făcut cele mai multe de cercetare---I'am pus împreună într-un ușor de utilizat bibliotecă.
În ultimele zile reprezintă prima mea lovitură de cuțit la codificare pe Android; aștepta mai mult să vină.
Aceasta este o combinat răspuns din două răspunsuri la partea de sus, dacă cineva dorește un lucru punere în aplicare.
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() {}
}
Puteți utiliza droidQuery biblioteca să se ocupe de aventuri, clicuri, lung click-uri, și evenimente personalizate. Punerea în aplicare este construit pe răspunsul meu anterior de mai jos, dar droidQuery oferă un slick, simplu sintaxa:
//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];
}
}
});
Acest răspuns folosește o combinație de componente de la alte răspunsuri aici. Se compune din SwipeDetector clasa, care are în interior o interfață pentru a asculta pentru evenimente. Am oferi, de asemenea, un RelativeLayout
pentru a arăta cum pentru a trece peste un "View" 's onTouch
metoda pentru a permite atât treceți evenimente și alte detectat evenimente (cum ar fi clicuri sau lung click-uri).
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);
}
}
Treceți Interceptor Vedere
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;
}
}
Știu că e prea târziu să răspundă, dar eu sunt Încă postarea Glisați pentru Detectarea ListView care Cum să utilizați Bețivan Atingere Ascultător în ListView Element.
Referinta: Exterminator13(unul dintre răspunsul în această pagină)
Face o 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);
}
}
Apel de clase de activitate astfel:
yourLayout.setOnTouchListener(new ActivitySwipeDetector(this, your_activity.this));
Și Don't uitați să implementarea SwipeInterface, care vă va oferi două @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");
}
Dacă nu vă place pentru a crea o clasă separată sau de a face un cod complex,
Puteți crea doar un GestureDetector variabilă în interiorul OnTouchListener și face codul mai ușor
namVyuVar poate fi orice nume de Vedere pe care aveți nevoie pentru a seta 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;
}
});
});
Gesturile sunt cele subtile mișcări pentru a declanșa interacțiuni între ecranul tactil și utilizator. Dureaza pentru o perioada de timp dintre prima atingere de pe ecran, până la punctul când ultimul deget frunze de suprafață.
Android ne oferă o clasa numita GestureDetector cu care putem detecta gesturi comune, cum ar fi apăsând în jos și în sus, trecând pe verticală și pe orizontală (aventură), lungi și scurte de presă, robinete duble, etc. și atașați de ascultătorii lor.
Activitate clasa pună în aplicare GestureDetector.OnDoubleTapListener (pentru robinet dublu gest de detectare) și GestureDetector.OnGestureListener interfețe și să pună în aplicare toate metode abstracte.Pentru mai multe informații. puteti vizita https://developer.android.com/training/gestures/detector.html . Prin
Pentru Demo-Ul De Testare.GestureDetectorDemo
Am nedded o mai generic Clasa , am luat Tomas's class și a adăugat o Interfață care trimite evenimente la Activitate sau Fragment. se va înregistra ascultător pe constructor astfel încât să fie sigur de a implementa o interfață sau un ClassCastException va fi thorwn. interfața returnează unul din cele patru finale int definite în clasă și va reveni la vizualizarea pe care a fost activat la.
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);
}
}