Android uygulamamda fling
hareket algılamasını çalıştırmak istiyorum.
Elimde 9 adet ImageView
içeren bir GridLayout
var. Kaynak burada bulunabilir: [Romain Guys's Grid Layout][4].
Aldığım bu dosya Romain Guy'ın Photostream uygulaması'ndan alınmıştır ve sadece biraz uyarlanmıştır.
Basit tıklama durumu için sadece View.OnClickListener
ı uygulayan ana aktivite
olmak üzere eklediğim her ImageView
için onClickListener
ı ayarlamam gerekiyor. Bir fling
i tanıyan bir şeyi uygulamak sonsuz derecede daha karmaşık görünüyor. Sanırım bunun nedeni görünümleri
kapsayabilmesi?
Eğer etkinliğim
OnGestureListener'ı nasıl yapacağımı bilmiyorum
için jest dinleyicisi olarak ayarlayın.
Grid
veya Image
görünümlerini
ekle.
public class SelectFilterActivity extends Activity uygular
View.OnClickListener, OnGestureListener { ...
Eğer etkinliğim
OnTouchListener
o zaman elimde
onFlingyöntemini
override` etmek için (bu
parametreler olarak iki olay bana izin veriyor
kaçamak olup olmadığını belirlemek için
kayda değer).
public class SelectFilterActivity extends Activity uygular
View.OnClickListener, OnTouchListener { ...
Eğer GestureImageView
gibi ImageView
'i genişleten özel bir View
yaparsam, aktiviteye görünümden bir fling
oluştuğunu nasıl söyleyeceğimi bilmiyorum. Her durumda, bunu denedim ve ekrana dokunduğumda yöntemler çağrılmadı.
Bunun görünümler arasında çalıştığına dair somut bir örneğe ihtiyacım var. Bu `dinleyiciyi' neye, ne zaman ve nasıl eklemeliyim? Tek tıklamaları da algılayabilmem gerekiyor.
// 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;
}
}
});
Uçuşları yakalamak için ekranımın üstüne şeffaf bir görünüm yerleştirmek mümkün mü?
Alt resim görünümlerimi XML'den şişirmemeyi
seçersem, GestureDetector'ı oluşturduğum yeni bir
ImageView` alt sınıfına yapıcı parametresi olarak geçirebilir miyim?
Bu, `fling' algılamasının çalışmasını sağlamaya çalıştığım çok basit bir etkinlik: SelectFilterActivity (Photostream'den uyarlanmıştır).
Bu kaynaklara bakıyordum:
Şimdiye kadar hiçbir şey işime yaramadı ve bazı ipuçları almayı umuyordum.
Kodunu kendi durumuma uyarladığım Code Shogun'a teşekkürler.
Aktivitenizin her zamanki gibi "OnClickListener" uygulamasına izin verin:
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;
}
}
}
Hareket dinleyicinizi ana düzene eklediğiniz tüm görünümlere ekleyin;
// Do this for each view added to the grid
imageView.setOnClickListener(SelectFilterActivity.this);
imageView.setOnTouchListener(gestureListener);
Hem activity'nin onClick(View v)
hem de gesture listener'ın `onFling'i olmak üzere, geçersiz kılınan metotlarınızın vurulmasını hayranlıkla izleyin.
public void onClick(View v) {
Filter f = (Filter) v.getTag();
FilterFullscreenActivity.show(this, input, f);
}
Dans sonrası 'kaçamak' isteğe bağlıdır ancak teşvik edilir.
Yukarıdaki kaydırma hareketi algılayıcı kodu çok kullanışlıdır! Bununla birlikte, mutlak değerler (SWIPE_)
yerine aşağıdaki göreli değerleri (REL_SWIPE)
kullanarak bu çözümü yoğunluktan bağımsız hale getirmek isteyebilirsiniz
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);
Ayrıca küçük bir geliştirme olarak.
try/catch bloğunun ana nedeni, e1'in ilk hareket için null olabilmesidir. try/catch'e ek olarak, null ve return için bir test ekleyin. aşağıdakine benzer
if (e1 == null || e2 == null) return false;
try {
...
} catch (Exception e) {}
return false;