Želim zaznavanje gest fling
za delovanje v svoji aplikaciji za Android.
Imam GridLayout
, ki vsebuje 9 ImageView
. Vir je na voljo tukaj: [Romain Guys's Grid Layout][4].
Datoteka, ki sem jo vzel, je iz aplikacije Photostream in je bila le nekoliko prilagojena.
Za preprost primer klika moram samo nastaviti onClickListener
za vsak ImageView
, ki ga dodam kot glavno aktivnost
, ki implementira View.OnClickListener
. Zdi se neskončno bolj zapleteno implementirati nekaj, kar bi prepoznalo fling
. Predvidevam, da je to zato, ker se lahko razteza čez pogledi
?
Če moja dejavnost implementira
OnGestureListener
, ne vem, kako naj
nastaviti kot poslušalca gest za
Mrežo
ali Sliko
, ki ju imam
dodati.
javni razred SelectFilterActivity razširja Activity implements
View.OnClickListener, OnGestureListener { ...
Če moja dejavnost implementira
OnTouchListener
, potem nimam
metodo onFling
, ki bi jo bilo treba prevzeti
(ima
dva dogodka kot parametra, kar mi omogoča, da
da lahko določim, ali je bil fling
vreden omembe).
javni razred SelectFilterActivity razširja Activity implements
View.OnClickListener, OnTouchListener { ...
Če naredim lasten Pogled
, kot je GestureImageView
, ki razširja ImageView
, ne vem, kako naj dejavnosti sporočim, da je prišlo do preklopa
iz pogleda. V vsakem primeru sem to poskusil in metode niso bile poklicane, ko sem se dotaknil zaslona.
V resnici potrebujem le konkreten primer delovanja tega v različnih pogledih. Kaj, kdaj in kako naj priključim tega poslušalca
? Znati moram zaznati tudi posamezne klike.
// 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;
}
}
});
Ali je mogoče na vrh zaslona položiti prozoren pogled, da bi zajel prelete?
Če se odločim, da svojih otroških slikovnih prikazov ne bom napihnil
iz XML, ali lahko GestureDetector
podam kot parameter konstruktorja novemu podrazredu ImageView
, ki ga ustvarim?
To je zelo preprosta dejavnost, za katero skušam doseči, da bi zaznavanje flinga
delovalo: SelectFilterActivity (Adapted from photostream).
Pregledal sem te vire:
Do zdaj mi ni nič pomagalo, zato sem upal na kakšne napotke.
Zahvaljujem se Code Shogun, katerega kodo sem prilagodil svojemu položaju.
Naj vaša aktivnost implementiraOnClickListener
kot običajno:
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;
}
}
}
Priključite poslušalca geste vsem pogledom, ki ste jih dodali v glavno postavitev;
// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this);
imageView.setOnTouchListener(gestureListener);
S strahospoštovanjem opazujte, kako so vaše prekrite metode dosežene, tako onClick(View v)
dejavnosti kot onFling
poslušalca geste.
public void onClick(View v) {
Filter f = (Filter) v.getTag();
FilterFullscreenActivity.show(this, input, f);
}
Ples po 'flingu' ni obvezen, vendar je priporočljiv.
Zgornja koda detektorja geste podrsavanja je zelo uporabna! Vendar pa boste morda želeli, da ta rešitev postane gostotno agnostična, tako da namesto absolutnih vrednosti (SWIPE_)
uporabite naslednje relativne vrednosti (REL_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);
Manjša izboljšava.
Glavni razlog za blok try/catch je, da je lahko e1 pri začetnem premiku nič. poleg bloka try/catch vključite še test za nič in vrnitev. Podobno kot v naslednjem primeru
if (e1 == null || e2 == null) return false;
try {
...
} catch (Exception e) {}
return false;