我有一個Activity
,裏面是ViewPager
和裏面是ListFragment
與ListView
項目。我想定義項目的觸摸手勢(拖動,跳動等)。結合多個onTouchListeners()
我可以通過重寫getView()
適配器將onTouchListener()
附加到每個ListView
項目View
。
Adapter adapter = new Adapter(blah, blah, blah) {
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View itemView = super.getView(position, convertView, parent);
itemView.setOnTouchListener(new View.OnTouchListener() {
blah, blah, blah
});
return itemView;
}
};
但我只收到MotionEvent.ACTION_DOWN
,MotionEvent.ACTION_MOVE
和MotionEvent.ACTION_UP
如果它裏面發生觸發項目View
邊界。例如,我無法趕上MotionEvent.ACTION_OUTSIDE
。
我的猜測是,我的自定義onTouchListener
與ViewPager
和Activity
的聽衆競爭。我想在某些場合觸發這些其他聽衆,也就是說,如果用戶移動到側面,我想滑動ViewPager
內的整個View
,但是如果他推動ListView
項目並垂直移動,我想要項目startDrag()
。
如何實施?
編輯/目前,關於ListView
項目我自定義監聽器的工作原理以及ViewPager
,這是偉大的。只要我不移動View
,我就可以抓取ListView
項目事件,並且我還可以在ViewPager
中滑動整個View
。
編輯/我已經重寫了我的ListView
到RecycledView
並意識到,如果我附上監聽器項目View
,該ViewPager
捕獲幾乎所有的移動事件,而只允許單擊事件經過。我也意識到,如果我將OnTouchListener
附加到RecycledList
它是能夠將移動事件與ViewPager
一起捕獲,因此它取決於我附加Listener
的哪個級別。問題是,在View
級別的項目中,我可以完全參考項目,而在使用列表時,我需要從事件座標中猜測項目位置,然後從Adapter中收集數據,這是額外的工作。
編輯/它畢竟並不難。幸運的是,RecycledView
有findChildViewUnder(int xPos, int yPos)
方法,所以得到View
是小菜一碟。
這裏是我的實現中,如果有人感興趣
mRecycledView.setOnTouchListener(new View.OnTouchListener() {
int LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout();
float mItemViewHeight, mInitialY;
boolean mIsResolved;
final Handler mHandler = new Handler(Looper.getMainLooper());
final Runnable mLongPress = new Runnable() {
@Override
public void run() {
mIsResolved = true;
onLongClick();
}
};
@Override
public boolean onTouch(View v, MotionEvent me) {
switch (MotionEventCompat.getActionMasked(me)) {
case MotionEvent.ACTION_DOWN:
mInitialY = me.getY();
mActiveUserView = mRecycledView.findChildViewUnder(me.getX(), mInitialY);
if (mActiveUserView == null) { // clicked to RecycledView where's no item
mIsResolved = true;
} else {
mIsResolved = false;
mItemViewHeight = (float) mActiveUserView.getHeight();
mHandler.postDelayed(mLongPress, LONG_PRESS_TIMEOUT);
}
break;
case MotionEvent.ACTION_MOVE:
if (!mIsResolved) {
stopLongClickHandler();
// check for vertical upward move
if (mInitialY - me.getY() > mItemViewHeight) {
mIsResolved = true;
onVerticalDrag();
}
}
break;
case MotionEvent.ACTION_UP:
if (!mIsResolved) {
stopLongClickHandler();
mIsResolved = true;
onClick();
}
}
return !mIsResolved;
}
void stopLongClickHandler() {
mHandler.removeCallbacksAndMessages(null);
}
void onVerticalDrag() {
Log.e("DEBUG", "start drag");
}
void onLongClick() {
Log.e("DEBUG", "long click");
}
void onClick() {
Log.e("DEBUG", "short click");
}
});
該教程很棒,但沒有幫助我完成我的任務。它描述瞭如何輕鬆地重新定位或刪除列表中的項目。我試圖實現的是通過在['Toolbar'](http://developer.android.com/reference/android/widget/Toolbar.html)中將項目拖動到按鈕上來執行刪除操作。 – Vaclav
然後你需要設置一個拖放監聽器到你的按鈕並實現相應的行爲 –