2012-04-06 91 views
18

在我的應用程序中,我想要在我的父視圖的onTouchListener中獲取所有子視圖的觸摸事件,但我無法獲取。如何在父視圖的touchlistener中使用子視圖的觸摸事件?

實施例:

在我的活動的觀點我有有一些按鈕和edittexts在它的一點的佈局。所以,無論何時我觸摸按鈕或編輯文本,我都希望在framlayout的onTouchListeners中獲得此觸摸事件。

這裏是我的代碼..

活動:

private FrameLayout rootView; 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     rootView = (FrameLayout) findViewById(R.id.rootview); 
     rootView.setOnTouchListener(new OnTouchListener() 
     { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) 
      { 
       Log.e("Touch Event: ", " X: " + event.getX() + " Y: " + event.getY()); 
       return false; 
      } 
     }); 
     } 

的main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="10dip" 
    android:id="@+id/rootview"> 

<LinearLayout 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="@android:color/white" 
    android:orientation="vertical" 
    android:layout_gravity="center" 
    android:padding="10dip"> 

    <TextView 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center" 
        android:padding="4dp" 
        android:text="Login" 
        android:textColor="@android:color/black" 
        android:textSize="16dp" 
        android:textStyle="bold" /> 

       <TextView 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_marginTop="10dp" 
        android:text="Username" 
        android:textColor="@android:color/black" 
        android:textSize="14dp" 
        android:textStyle="bold" /> 

       <EditText 
        android:id="@+id/edttextusername" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:imeOptions="flagNoExtractUi" 
        android:singleLine="true" /> 

       <TextView 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_marginTop="10dp" 
        android:text="Password" 
        android:textColor="@android:color/black" 
        android:textSize="14dp" 
        android:textStyle="bold" /> 

       <EditText 
        android:id="@+id/edttextpassword" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:imeOptions="flagNoExtractUi" 
        android:password="true" /> 

       <LinearLayout 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center" 
        android:gravity="center" 
        android:orientation="horizontal" 
        android:padding="10dp" > 

        <Button 
         android:id="@+id/btnlogin" 
         android:layout_width="0dip" 
         android:layout_height="40dip" 
         android:layout_marginRight="5dp" 
         android:layout_weight="1" 
         android:enabled="false" 
         android:text="Login" 
         android:padding="5dip" 
         android:textColor="@android:color/black" 
         android:textStyle="bold" 
         /> 

        <Button 
         android:id="@+id/btncall" 
         android:layout_width="0dip" 
         android:layout_height="40dip" 
         android:layout_marginLeft="5dp" 
         android:layout_weight="1" 
         android:padding="5dip" 
         android:text="Cancel" 
         android:textColor="@android:color/black" 
         android:textStyle="bold" /> 
       </LinearLayout> 


</LinearLayout> 

    </FrameLayout> 

問題:所以whenver我觸摸按鈕或EditText上在我的框架佈局的onTouchLi中,我無法獲得聯繫(不叫)。

注意:我不想爲所有childView添加單獨的onTouchListener。

在此先感謝。

回答

3

我嘗試過類似的設計(在根FrameLayout上只有一個onTouch監聽器)並且它工作正常。如果onTouch返回true而不是false,我會得到所有要點。否則,我只是得到第一點。我無法找到這個「返回」問題的原因,因爲我預料會出現相反的行爲。

但是,根據我的經驗,如果您設置任何子視圖可點擊,那麼其父級的onTouch將無法工作。如果你有另一種解決方案,如果你分享,那會很棒。

22

您可以通過在佈局中重寫dispatchTouchEvent來實現該目標。

public class MyFrameLayout extends FrameLayout { 
    @Override 
    public boolean dispatchTouchEvent(MotionEvent e) { 
     // do what you need to with the event, and then... 
     return super.dispatchTouchEvent(e); 
    } 
} 

然後使用該佈局代替通常的FrameLayout的:

<com.example.android.MyFrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:padding="10dip" 
    android:id="@+id/rootview"> 
    ... 

你也可以跳過超級呼叫完全,如果你需要,以防止孩子的意見接收事件,但我認爲這會很少見。如果您需要重新創建一些,但不是所有的默認功能,還有很多改寫:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/view/ViewGroup.java#ViewGroup.dispatchTouchEvent%28android.view.MotionEvent%29

2

2個解決方案:

  1. 的ViewGroup中使用onInterceptTouchEvent,如圖所示 here

  2. 避免讓佈局處理觸摸事件,並且有一個視圖是佈局的子視圖,它覆蓋整個大小以處理觸摸事件。

    它不像擴展類一樣高效,但它更容易,不需要創建新的文件/類。

    例如:

    觸摸事件,只是添加到視圖,它會處理它們,而不是任何其他意見。

-1

它可以通過使用「onInterceptTouchEvent」來實現。請嘗試此操作,它可能會工作

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    onTouchEvent(ev); 
    return false; 
} 
+0

手動調用onTouchEvent方法不是一個好主意... – Crisic 2017-06-07 14:29:44

相關問題