2011-04-13 62 views
11

我有一個充滿按鈕的屏幕,但是想讓onTouch-method使用整個屏幕的座標。我第一次嘗試使用帶有onTouchListener的RelativeLayout,但從未設法使其與監聽器「連接」(即在觸摸屏幕時沒有發生任何事情),我也嘗試將ImageView放在屏幕頂部,然後使該視圖不可見。整個屏幕的onTouchListener

這最後一個方法給了onClicks正確的迴應,但我從來沒有設法讓它看不見。

如果這是最好的解決方案,我非常懷疑,我該如何讓ImageView完全不可見,而不會丟失它的onTouchListener(我已經試用了white backgroundColor和setAlpha(0))。

我可以以某種方式使onTouchListener對整個屏幕作出反應,使用全局座標,而屏幕顯示(和改變)幾個按鈕(最好沒有不可見的imageview)?

如果你不明白我在問什麼,隨時抱怨。我會盡量填補需要的空白。

編輯:

我現在已經成功使用常規onTouch的方法來解決這個問題。我遇到了幾個問題,使ACTION_DOWN和ACTION_MOVE都激活了按鈕,但我終於得到了它的工作。對於其他人閱讀:onInterceptTouchEvent可能會被使用(但我從來沒有想出如何獲得屏幕座標,而不是視圖座標)。

回答

8

對不起,如果我錯了,但我相信我剛剛有類似的問題。我想要一個標題屏幕,顯示一張圖片和圖片上的單詞,說「點擊繼續」或類似的東西。我搞砸了一下,發現你可以使佈局可點擊。

android:focusable="true" 
    android:id="@+id/titlescreenframe"> 

是我的xml文件,用於我的佈局。背景圖像是簡單地在後臺屬性(我知道你不使用圖像)

不管怎樣,回到我的活動

private FrameLayout fl; 
    ... 
    fl = (FrameLayout)findViewById(R.id.titlescreenframe); 
    fl.setOnClickListener(this); 

然後我使用switch語句來處理和按鈕,在下一個佈局。在這裏,如果你需要它:Using Switch Statement to Handle Button Clicks

似乎這應該與其他佈局,以及我的主要佈局沒有字面上任何意見。 (除非佈局本身算作一個?)

哈!剛纔意識到你說你找到了解決方案。愚蠢的時機。我會發布這個幫助別人的機會,讓每個人都快樂。 :)

+2

如果你的目標比1.6更新,你可以直接使用android:onClick =「functionname」而不是設置focusable,並在代碼中分配onclick監聽器。 – Yenchi 2012-01-19 23:31:04

3

您是否在版面上嘗試過onInterceptTouchEvent

+0

Dsouza我嘗試過,但並不滿足。我現在通過使用常規的onTouch方法設法解決了這個問題。我遇到了幾個問題,使ACTION_DOWN和ACTION_MOVE都激活了按鈕,但我終於得到了它的工作。對於其他人閱讀:onInterceptTouchEvent可能會被使用(但我從來沒有想出如何獲得屏幕座標,而不是視圖座標)。 – keyser 2011-04-17 16:03:07

3

我用dispatchTouchEvent一個類似的問題。您可以認爲它是onTouchEvent的直接替代品,只是它始終向您發送一個事件,即使它是在現有視圖之上。

如果您處理該事件,則返回true,否則請務必呼叫super.dispatchTouchEvent()並返回其結果。

至於獲取屏幕座標 - 只需調用MotionEvent的getRawX()getRawY()而不是getX()getY()。這些是絕對的屏幕座標,包括操作欄和全部。如果你想交叉引用那些視圖,getLocationOnScreen可能是最簡單的解決方案。

1

觸摸事件首先返回到子視圖。並且如果您爲它們定義onClick或onTouch偵聽器,parnt視圖(例如片段)將不會收到任何觸摸偵聽器。所以,如果你想在這種情況下定義片段刷卡偵聽器,必須在一個新的類實現它:

package com.neganet.QRelations.fragments; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.widget.FrameLayout; 

public class SwipeListenerFragment extends FrameLayout { 
    private float x1,x2; 
    static final int MIN_DISTANCE=150; 
    private onSwipeEventDetected mSwipeDetectedListener; 


    public SwipeListenerFragment(Context context) { 
     super(context); 
    } 

    public SwipeListenerFragment(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public SwipeListenerFragment(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     boolean result=false; 
     switch(ev.getAction()) 
     { 
      case MotionEvent.ACTION_DOWN: 
       x1 = ev.getX(); 
       break; 
      case MotionEvent.ACTION_UP: 
       x2 = ev.getX(); 
       float deltaX = x2 - x1; 
       if (Math.abs(deltaX) > MIN_DISTANCE) 
       { 
        if(deltaX<0) 
        { 
         result=true; 
         if(mSwipeDetectedListener!=null) 
          mSwipeDetectedListener.swipeLeftDetected(); 

        }else if(deltaX>0){ 
         result=true; 
         if(mSwipeDetectedListener!=null) 
          mSwipeDetectedListener.swipeRightDetected(); 
        } 
       } 
       break; 
     } 
     return result; 
    } 

    public interface onSwipeEventDetected 
    { 
     public void swipeLeftDetected(); 
     public void swipeRightDetected(); 

    } 

    public void registerToSwipeEvents(onSwipeEventDetected listener) 
    { 
     this.mSwipeDetectedListener=listener; 
    } 
} 

你可以實現對其他類型的佈局完全是這樣。這個類可以檢測左右滑動,特別是檢測後返回onInterceptTouchEvent true。它的重要性在於,如果我們不這樣做,有時候子視圖可能會接收事件,而且對於子視圖(例如)的片段和onClick都會運行並導致一些問題。 使得這個類後,你必須改變你的片段xml文件:

<com.neganet.QRelations.fragments.SwipeListenerFragment xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" 
    android:id="@+id/main_list_layout" 
    android:clickable="true" 
    android:focusable="true" 
    android:focusableInTouchMode="true" 
    android:layout_height="match_parent" tools:context="com.neganet.QRelations.fragments.mainList" 
    android:background="@color/main_frag_back"> 

    <!-- TODO: Update blank fragment layout --> 
    <android.support.v7.widget.RecyclerView 
     android:id="@+id/farazList" 
     android:scrollbars="horizontal" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_gravity="left|center_vertical" /> 
</com.neganet.QRelations.fragments.SwipeListenerFragment> 

你看到的開始標記是我們做的類。現在片段類:

  View view=inflater.inflate(R.layout.fragment_main_list, container, false); 
     SwipeListenerFragment tdView=(SwipeListenerFragment) view; 
     tdView.registerToSwipeEvents(this); 


and then Implement SwipeListenerFragment.onSwipeEventDetected in it: 

     @Override 
    public void swipeLeftDetected() { 
     Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show(); 
    } 

    @Override 
    public void swipeRightDetected() { 
     Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show(); 
    } 

這是一個有點複雜,但完美的作品:)