2012-06-01 41 views
26

我打電話的onTouchEvent()不會,如果setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)被調用

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) 

當我的應用程序開始做我的應用程序能夠顯示全屏觸發。

我希望我的應用程序的用戶界面在觸摸屏幕時彈出,但Activity.onTouchEvent()直到屏幕再次被觸摸纔會觸發。首先,只顯示虛擬鍵。

所以,我要觸發我的應用程序的用戶界面上彈出

public void onSystemUiVisibilityChange(int visibility) { 
    if (visibility == View.SYSTEM_UI_FLAG_VISIBLE) { 
     // show my APP UI 
    } 
} 

onSystemUiVisibilityChangeView.SYSTEM_UI_FLAG_VISIBLE將由系統每沾不調用一次(3次我的Galaxy Nexus),特別是如果用戶非常快速/經常地觸摸屏幕。

項目庫4.0或4.03。三星銀河(9250)與4.03。

+0

我也可以確認這種情況正在發生。錯誤? – dell116

+0

是否將它作爲服務運行? –

+0

我也是。這我不能在我的視頻視圖上使用手勢。 –

回答

0

您是否曾嘗試添加代碼以僅在狀態發生變化時才顯示您的用戶界面?你必須保持最後已知的知名度,只能說明你的用戶界面,當你第一次來到可見:從Android docs

+0

我不認爲你已經理解了這個問題。這並不能解決問題。 – peedee

-1

採用Activity.onTouchEvent()被稱爲在年底方法

int mLastSystemUiVis; 

@Override 
public void onSystemUiVisibilityChange(int visibility) { 
    int diff = mLastSystemUiVis^visibility; 
    mLastSystemUiVis = visibility; 
    if ((diff&SYSTEM_UI_FLAG_VISIBLE) != 0 
      && (visibility&SYSTEM_UI_FLAG_VISIBLE) == 0) { 
     // DISPLAY YOUR UI 
    } 
} 

代碼示例的響應者鏈(意味着在所有其他觀點都有機會消費該事件之後)。如果您點擊有興趣聯繫的視圖(即ButtonEditText),您的活動絕對不會看到該活動。

如果你想有機會獲得觸摸他們每天得到分派到您的視圖(S)之前,覆蓋Activity.dispatchTouchEvent()相反,這是開始的事件鏈的稱爲在方法:

@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 
    //Check the event and do magic here, such as... 
    if (event.getAction() == MotionEvent.ACTION_DOWN) { 

    } 

    //Be careful not to override the return unless necessary 
    return super.dispatchTouchEvent(event); 
} 

請注意不要重寫此方法的返回值,除非您有意從其餘視圖中竊取觸摸,否則此處的不必要的return true;將打破其他觸摸處理。

+0

不幸的是,這是行不通的。 – user1256821

+0

這在概念上正確並且很好記住一般,但它在這個特定問題中失敗。當我嘗試它時,dispatchTouchEvent在第一次觸摸時也沒有被調用。 – peedee

0

我有一個非常類似的問題,試圖更新從onTouchEvent()需要兩個接觸工作的UI,我試了一堆精心設計的東西,最終讓它在第一次點擊工作。

在我的情況下,我顯示了一個先前隱藏的項目,然後獲取它的高度,然後將按鈕向下移動那個高度。我遇到的問題是高度顯示爲0,直到第一次觸摸事件結束。我可以通過調用show()在ACTION_UP中爲onTouchEvent()而不是ACTION_DOWN來解決此問題。也許它會工作,如果你做了類似的事情?

+0

如果您需要第一個ACTION_DOWN的位置,這不起作用。 – peedee

0

嘗試使用:

getWindow()getDecorView()setSystemUiVisibility(View.GONE);

代替:

getWindow()getDecorView()setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)

這之後,你可以在全屏使用正常的活動,如果你想導航鍵,你需要從底部滑動即可。向上。對於我來說的Galaxy Tab 2採用Android 4.1.2

1

工作這沒有工作對我來說:

setOnSystemUiVisibilityChangeListener(new OnSystemUiVisibilityChangeListener() { 
     @Override 
     public void onSystemUiVisibilityChange(int visibility) { 
      if ((visibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { 
       // show my app UI 
      } 
     } 
    }); 
+1

這是如何幫助對問題中所述的第一觸摸事件做出反應? – peedee

1

我做什麼是第一個導入android.view.GestureDetector這樣我就可以用它來檢測手勢。 Android有許多默認手勢,可在GestureDector class中自動檢測到。大部分信息都是here,但下面的代碼是我在實際項目中使用的一種形式。

首先,我在我的Activity中創建了一個匿名類(它可以嵌套到任何地方,但我傾向於在右下角的右括號處使用匿名類)。注意:您也可以實施OnGestureListener作爲班級的一部分。

下面的代碼是用於使用手勢檢測來給出一個簡單的隱藏/顯示。

我已經聲明並定義了我的操作欄(我的UI,它最初是隱藏的)作爲一個實例變量,所以我可以在這裏和其他任何地方訪問它,但是您可以用它代替getActionBar().show()getActionBar().hide()如果您不想將其聲明爲實例變量。替換在這裏actionBar的地方你的用戶界面:

public class Example extends ActionBarActivity { 

    // declared in onCreate() method 
    private android.support.v7.app.ActionBar actionBar; 
    private GestureDetectorCompat mDetector; 
    private YourView view1; 
    private YourView view2; 
    private YourView view3; 
    private YourView view4; 

    // some other code 

    class GestureListener extends GestureDetector.SimpleOnGestureListener { 

    private static final String DEBUG_TAG = "Gestures in Example Class"; 

     @Override 
     public boolean onDoubleTap(MotionEvent event) { 

      Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString()); 
      // if there is a double tap, show the action bar 
      actionBar.show(); 

      return true; 
     } 

     @Override 
     public boolean onSingleTapConfirmed(MotionEvent event) { 

      Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString()); 

      // if the tap is below the action bar, hide the action bar 
      if (event.getRawY() > getResources().getDimension(R.dimen.abc_action_bar_default_height)) { 
       actionBar.hide(); 
       return true; 
      } 

      return false; 
     } 

     @Override 
     public boolean onDown(MotionEvent event) { 

      return true; 

     } 

} // end-of-Example Class 

然後在我的onCreate()我宣佈我的GestureDetector並(可選)設置我的GestureListeners

private GestureDetectorCompat mDetector; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // some code here 
    mDetector = new GestureDetectorCompat(this, new GestureListener()); 

    // this code is for more advanced view logic not needed for a basic set-up 
    //setGestureListeners(); 

} // end-of-method onCreate() 

然後以實際發送手勢待處理我們提供了這樣做的說明,我知道有兩種方式,第一種最簡單:

/** 
* This method recognizes a touchEvent and passes it to your custom GestureListener 
* class. 
*/ 
@Override 
public boolean onTouchEvent(MotionEvent event){ 

    this.mDetector.onTouchEvent(event); 

    return super.onTouchEvent(event); 
} 

第二種方法比較複雜,但如果只想識別佈局中某些View的觸摸事件,就像在重疊視圖並且只能訪問頂部View的情況下一樣,您可以創建一個自定義類來傳遞事件周圍或達:

class MyOnTouchListener implements View.OnTouchListener { 

    public boolean onTouch(View v, MotionEvent event) { 

     if (v.equals(view4)) { 
      return mDetector.onTouchEvent(event); 
     } else return false; 
    } 
} // end-of-class MyOnTouchListener 

,然後在這裏使用它:

public void setGestureListeners() { 

    /* when we return false for any of these onTouch methods 
    * it means that the the touchEvent is passed onto the next View. 
    * The order in which touchEvents are sent to are in the order they 
    * are declared. 
    */ 
    view1.setOnTouchListener(new MyOnTouchListener()); 

    view2.setOnTouchListener(new MyOnTouchListener()); 

    view3.setOnTouchListener(new MyOnTouchListener()); 

    view4.setOnTouchListener(new MyOnTouchListener()); 


} // end-of-method setGestureListeners() 

在我setGestureListeners方法,我給他們所有相同的命令集,基本上只能識別上view4 touchEvents。否則,它只是將touchEvent傳遞給下一個視圖。

這是使用AppCompat的代碼,但如果您不是爲舊版本構建的,則可以使用常規的GestureDetectorActionBar

2

Android 4.4(API等級19)爲setSystemUiVisibility()引入了一個新的SYSTEM_UI_FLAG_IMMERSIVE標誌,可以讓您的應用真正成爲「全屏」。此標誌與SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN標誌組合時隱藏導航欄和狀態欄,並讓您的應用程序捕獲屏幕上的所有觸摸事件。