Подтвердить что ты не робот

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

но onSystemUiVisibilityChange с View.SYSTEM_UI_FLAG_VISIBLE будет вызываться не один раз за одно касание (3 раза на моем Galaxy Nexus) системой, особенно если пользователь очень быстро или часто прикасается к экрану.

project lib 4.0 или 4.03. Галактика Samsung (9250) с 4.03.

4b9b3361

Ответ 1

Android 4.4 (API уровня 19) представляет новый SYSTEM_UI_FLAG_IMMERSIVE флаг для setSystemUiVisibility(), который позволяет вашему приложению по-настоящему "полноэкранный". Этот флаг в сочетании с флагами SYSTEM_UI_FLAG_HIDE_NAVIGATION и SYSTEM_UI_FLAG_FULLSCREEN скрывает строки навигации и состояния и позволяет вашему приложению захватывать все сенсорные события на экране.

Ответ 2

Это работало для меня:

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

Ответ 3

Сначала я импортировал android.view.GestureDetector, чтобы я мог использовать его для обнаружения жестов. Android имеет ряд жестов по умолчанию, которые автоматически обнаруживаются в классе GestureDector. Большая часть этой информации находится здесь здесь, но ниже приведен код в форме, которую я использовал в фактическом проекте, который работает.

Сначала я сделал анонимный класс в моей деятельности (это может быть вложенным везде, но я склонен сделать мои анонимные классы внизу, прямо перед закрывающей скобкой). ПРИМЕЧАНИЕ. Вы также можете реализовать OnGestureListener как часть своего класса.

Нижеприведенный код предназначен для использования обнаружения жестов, чтобы дать простое скрытие/шоу.

Я объявил и определил свою панель действий (мой пользовательский интерфейс, который изначально скрыт) в качестве переменной экземпляра, поэтому я могу получить доступ к нему здесь и где угодно, но вы можете заменить его на 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 я дал им все тот же набор команд, который по существу только распознает touchEvents на view4. В противном случае он просто передает touchEvent к следующему виду.

Это код с использованием AppCompat, но если вы не создаете более старые версии, вы можете использовать обычные GestureDetector и actionBar.

Ответ 4

Вы пытались добавить код, чтобы показывать только свой пользовательский интерфейс, когда состояние изменилось? Вы должны поддерживать последнюю известную видимость и показывать свой интерфейс только тогда, когда вы впервые видитесь:

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-документов

Ответ 5

У меня тоже возникла эта проблема, и я нашел это http://developer.android.com/reference/android/view/View.html#SYSTEM_UI_FLAG_HIDE_NAVIGATION

Таким образом, никоим образом не помогать. Даже приложение, настроенное в системе Android, использовало SYSTEM_UI_FLAG_LOW_PROFILE вместо SYSTEM_UI_FLAG_HIDE_NAVIGATION на странице просмотра фото. Это, по крайней мере, то, что мы можем сделать.

Ответ 6

У меня была очень похожая проблема с попыткой обновить пользовательский интерфейс от onTouchEvent(), требуя двух действий для работы, и я попробовал кучу сложных вещей, прежде чем, наконец, заставить его работать с первым щелчком.

В моем случае я показывал ранее скрытый элемент, затем получаю его высоту, а затем перемещаю кнопку на эту высоту. Проблема, с которой я столкнулся, заключается в том, что высота показывалась как 0 до окончания первого события касания. Я смог решить это, вызвав show() во время ACTION_UP для onTouchEvent() вместо ACTION_DOWN. Может быть, это сработает, если вы сделали что-то подобное?

Ответ 7

Попробуйте использовать:

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

вместо:

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

После этого вы можете использовать обычную активность в полноэкранном режиме, и если вам нужны навигационные клавиши, вам нужно прокручивать снизу вверх. Работа для меня на Galaxy Tab 2 с android 4.1.2

Ответ 8

Метод Activity.onTouchEvent() вызывается в end цепи ответчика (это означает, что после того, как все другие представления имели возможность использовать событие). Если вы нажмете на интересующее вас мнение (т.е. A Button или EditText), у вас будет шанс, что ваша активность никогда не увидит это событие.

Если вы хотите иметь доступ к касаниям до того, как они будут отправлены на ваш взгляд, переопределите 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; в этом месте нарушит другую обработку касания.