2015-12-29 58 views
0

我有一個Activity,裏面是ViewPager和裏面是ListFragmentListView項目。我想定義項目的觸摸手勢(拖動,跳動等)。結合多個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_DOWNMotionEvent.ACTION_MOVEMotionEvent.ACTION_UP如果它裏面發生觸發項目View邊界。例如,我無法趕上MotionEvent.ACTION_OUTSIDE

我的猜測是,我的自定義onTouchListenerViewPagerActivity的聽衆競爭。我想在某些場合觸發這些其他聽衆,也就是說,如果用戶移動到側面,我想滑動ViewPager內的整個View,但是如果他推動ListView項目並垂直移動,我想要項目startDrag()

如何實施?


編輯/目前,關於ListView項目我自定義監聽器的工作原理以及ViewPager,這是偉大的。只要我不移動View,我就可以抓取ListView項目事件,並且我還可以在ViewPager中滑動整個View


編輯/我已經重寫了我的ListViewRecycledView並意識到,如果我附上監聽器項目View,該ViewPager捕獲幾乎所有的移動事件,而只允許單擊事件經過。我也意識到,如果我將OnTouchListener附加到RecycledList能夠將移動事件與ViewPager一起捕獲,因此它取決於我附加Listener的哪個級別。問題是,在View級別的項目中,我可以完全參考項目,而在使用列表時,我需要從事件座標中猜測項目位置,然後從Adapter中收集數據,這是額外的工作。


編輯/它畢竟並不難。幸運的是,RecycledViewfindChildViewUnder(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"); 
     } 
    }); 

回答

2

我可以建議你用RecyclerView更換ListView。然後閱讀this tutorial:它幾乎包含RecyclerView上的每個拖/滑/觸摸實現,都有清楚的說明。

+0

該教程很棒,但沒有幫助我完成我的任務。它描述瞭如何輕鬆地重新定位或刪除列表中的項目。我試圖實現的是通過在['Toolbar'](http://developer.android.com/reference/android/widget/Toolbar.html)中將項目拖動到按鈕上來執行刪除操作。 – Vaclav

+0

然後你需要設置一個拖放監聽器到你的按鈕並實現相應的行爲 –