2

我想實現一個自定義列表視圖,它允許兩個滑動和單擊按鈕,類似於飛旋鏢電子郵件客戶端實現的實現(或iOS郵箱)。實現一個listItem onClickListener而不消耗觸摸事件

如果我只想點擊列表項目本身,我可以創建一個新的OnItemClickListener,並確保沒有可聚焦或可點擊的後代,它們不消耗觸摸事件,並允許自定義列表視圖檢測輕掃。但是,如果我在列表項中單擊任何東西,它將消耗觸摸事件,不調用OnItemClickListener,並禁用自定義列表本身的滑動功能。

我已經嘗試創建onTouchListener的自定義實現,或使用自定義視圖組的onInterceptTouchEvent。對於所有這些實現,onTouchListener必須在Action.DOWN上返回true(並因此消耗觸摸事件),否則它將停止聆聽觸摸事件的其餘部分。

爲什麼OnItemClickListener可以在不消耗觸摸事件的情況下檢測觸摸,以及如何將其複製到我自己的自定義實現中?任何幫助或指針讚賞!

Boomerang swipable and clickable list functionality

下面是其中的工作原理,並且不消耗觸摸事件OnItemClickListener:

private AdapterView.OnItemClickListener onClick = new AdapterView.OnItemClickListener() 
    { 
     @Override 
     public void onItemClick(AdapterView<?> adapterView, View v, int position, 
       long arg3) { 

      mAction = mAdapter.getItem(position); 
      updateListToShowCurrentAction(); 
      return; 
     } 
    }; 

下面是我想能夠實現列表項中的視圖功能,同時還將觸摸事件傳遞到自定義列表視圖:

cancelButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
        final int position = mListView.getPositionForView((View) v.getParent()); 
        mReordCtrl.removeAction(mAdapter, position);   
      } 
     }); 

以下是list_item中的佈局片段:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:tag="list_item" > 

    <LinearLayout 
      android:id="@+id/back" 
      android:layout_width="match_parent" 
      android:layout_height="fill_parent" 
      android:layout_gravity="center_vertical" 
      android:orientation="horizontal" 
      android:tag="back" > 

      <ImageView 
       android:id="@+id/cancel_button" 
       android:layout_width="0dp" 
       android:layout_height="fill_parent" 
       android:layout_weight="1" 
       android:src="@drawable/ic_action_cancel" 
       android:tag="cancel_button" /> 
      </LinearLayout> 

回答

5

如果您已經玩過onInterceptTouchEvent,請嘗試重寫onTouchEvent(MotionEvent e)。這裏有一個示例實現,可以適應您的需求,它將SimpleOnGestureListener檢測器和可用於回調的自定義接口viewListener集成到父類中。如果你只是想檢測點擊,你可能不需要所有這些;你可能能夠擺脫手勢檢測器。另外,這裏有一個link當我研究觸摸事件處理時,我發現它很有用。

@Override public boolean onTouchEvent(MotionEvent ev) { 
    //See if the gesture detector has detected an event. 
    boolean eventConsumed = detector.onTouchEvent(ev); 
    if (!eventConsumed) { 

     //If no gesture detected, and the motion is finished, do something 
     if (ev.getAction() == MotionEvent.ACTION_UP) { 
      //DO SOMETHING, such as scroll 

      //Send event to listener. 
      if (viewListener != null) { 
       this.viewListener.onUp(ev.getX()); 
      } 
      return true; //Consume the event, so nothing else fires. 
     } else { 
      //If no event is detected, and the action hasn't finished, do the default behavior 
      return super.onTouchEvent(ev); 
     } 
    } else { 
     return true; //Consume the event, so nothing else fires. You can change this to false if you'd like to not consume the event. 
    } 

} 

和一個自定義的垂直滾動視圖類捕獲向下滑動,但將所有其他手勢傳遞給孩子。

public class VerticalScrollView extends ScrollView { 
private GestureDetector mGestureDetector; 
View.OnTouchListener mGestureListener; 

public VerticalScrollView(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    mGestureDetector = new GestureDetector(context, new YScrollDetector()); 
    setFadingEdgeLength(0); 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    boolean superBool = super.onInterceptTouchEvent(ev); 
    boolean intercept = mGestureDetector.onTouchEvent(ev); 
    return superBool && intercept ; 
} 

// Return false if we're scrolling more in the x direction than in the y direction, so we don't claim the action. 
class YScrollDetector extends SimpleOnGestureListener { 
    @Override 
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
     return Math.abs(distanceY) > Math.abs(distanceX); 
    } 
} 

}

+0

我敢肯定,我失去了一些東西,因爲據我所知,只有這樣,才能得到手勢的整體就這樣Action.DOWN消耗返回true在知道它是觸摸還是滑動之前,先運動的其餘部分。這個想法是在列表視圖中實現滑動並觸及list_item視圖,但我研究這個的時間越長,我越懷疑這種功能是不可能的,這是由於android實現了消費觸摸事件的方式。 –

+0

這完全有可能。我有一個包含頂級垂直滾動視圖的活動,其中包含一些可點擊的項目(包括視圖和按鈕)以及支持點擊和水平滑動的自定義幻燈片類。它花了一些時間來實現它的工作。我使用onScroll GestureDetector子類化滾動視圖並重寫onInterceptTouchEvent以捕獲垂直滾動。所有其他事件都由孩子處理,上面的代碼是自定義幻燈片類的一部分。我將垂直滾動視圖代碼添加到我的答案中,希望它有幫助。 – GLee

+0

非常感謝您的幫助!我遵循你的建議,並有一個自定義父視圖處理所有非點擊觸摸事件。我仍在努力獲得與我正在使用的圖書館相同的功能,但我認爲我現在正走在正確的道路上。 –