如果调用setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION),则不会触发onTouchEvent()

我打电话

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

当我的应用程序开始让我的应用程序能够显示全屏。

我希望在触摸屏幕时popup我的应用程序UI,但在第二次触摸屏幕之前不会触发Activity.onTouchEvent() 。 首次触摸时,仅显示虚拟键。

所以,我必须触发我的应用程序的UI才能popup

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

但是onSystemUiVisibilityChange会调用带有View.SYSTEM_UI_FLAG_VISIBLE而不是每次触摸(我的Galaxy Nexus上3次),特别是如果用户非常快/经常触摸屏幕。

项目lib 4.0或4.03。 三星Galaxy(9250)4.03。

  • 如何在Android片段中获取aptPackageManager
  • Android PowerManager WakeLock - 已弃用
  • Android - IllegalStateException:map的大小为零
  • 封面艺术在android上
  • 你如何在android中获得用户定义的“设备名称”?
  • 适用于Android的Google Play音乐API
  • 如何在eclipse中使用traceview进行android开发?
  • GoogleApiClient登录失败
  • Android 4.4(API Level 19)为setSystemUiVisibility() )引入了一个新的SYSTEM_UI_FLAG_IMMERSIVE标志,让你的应用真正“全屏”。 此标志与SYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_FULLSCREEN标志结合使用时,会隐藏导航和状态栏,并让您的应用程序捕获屏幕上的所有触摸事件。

    这对我有用:

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

    我做的是先导入android.view.GestureDetector所以我可以用它来检测手势。 Android有许多默认手势,可以在GestureDector类中自动检测到。 大部分信息都可以在这里find,但下面是我在实际项目中使用的表单中的代码。

    首先,我在我的Activity中创建了一个匿名类(这可以嵌套在任何地方,但我倾向于在底部,在结束括号之前创建我的匿名类)。 注意:您也可以将OnGestureListener实现为类的一部分。

    下面的代码用于使用手势检测来进行简单的隐藏/显示。

    我已经声明并定义了我的操作栏(我的UI,最初是隐藏的)作为实例variables,所以我可以在这里访问它,无论在哪里,但你可以用它代替getActionBar().show()getActionBar().hide()如果你不想将它声明为实例variables。 在actionBar的位置替换您的UI:

     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上的view4 。 否则,它只是将touchEvent传递给下一个视图。

    这是使用AppCompat代码,但如果您不是为旧版本构建,则可以使用常规的GestureDetectorActionBar

    您是否尝试添加代码以仅在状态发生变化时显示您的UI? 您必须保持上次已知的可见性,并且只有在您第一次看到时才会显示您的用户界面:

     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 } } 

    从Android文档中采用的代码示例

    我也遇到了这个问题,我发现了这个http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION

    所以,没办法帮忙。 甚至android系统打包的Gallery应用程序在照片页面视图中使用SYSTEM_UI_FLAG_LOW_PROFILE而不是SYSTEM_UI_FLAG_HIDE_NAVIGATION。 这至少是我们能做的。

    我有一个非常类似的问题,尝试从onTouchEvent()更新UI需要两个触摸工作,我尝试了一堆精心设计的东西,最后让它在第一次点击工作。

    在我的情况下,我正在显示一个先前隐藏的项目,然后获得它的高度,然后向下移动该高度的按钮。 我遇到的问题是,在第一次触摸事件结束后,高度显示为0。 我能够通过在ACTION_UP期间为onTouchEvent()而不是ACTION_DOWN调用show()来解决这个问题。 也许如果你做了类似的事情它会起作用吗?

    尝试使用:

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

    代替:

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

    之后,您可以在全屏中使用常规活动,如果您需要导航键,则需要从下往上滑动。 使用android 4.1.2在Galaxy Tab 2上为我工作

    Activity.onTouchEvent()方法在响应者链的末尾被调用(意味着在所有其他视图都有机会使用该事件之后)。 如果您点击对触摸感兴趣的视图(即ButtonEditText ),您的活动很可能永远不会看到该事件。

    如果您希望在每次调度到视图之前都有访问权限,请改为覆盖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; 在这个位置将打破其他触摸处理。