OnTouchListener для всего экрана

У меня есть экран, заполненный кнопками, но хочу, чтобы метод onTouch использовал все координаты экрана. Я сначала попытался использовать RelativeLayout с onTouchListener, но так и не смог заставить его «подключиться» к слушателю (т. Е. Ничего не происходило, когда экран был затронут), я также попытался помещать ImageView поверх экрана, а затем сделать это представление невидимым ,

Этот последний метод дал правильные ответы на onClicks, но мне никогда не удавалось сделать его невидимым.

Если это лучшее решение, которое я очень сомневаюсь, как сделать ImageView совершенно невидимым, не теряя его onTouchListener (я экспериментировал с белым фоном Color и setAlpha (0)).

Могу ли я каким-то образом заставить onTouchListener реагировать на весь экран, используя глобальные координаты, в то время как на экране отображаются (и изменяются) несколько кнопок (желательно без невидимого изображения)?

Если вы не понимаете, о чем я прошу, не стесняйтесь об этом. Я постараюсь заполнить пробелы по мере необходимости.

Редактировать:

Теперь мне удалось решить проблему, используя обычный метод onTouch. Я столкнулся с несколькими проблемами, так как ACTION_DOWN и ACTION_MOVE активировали кнопки, но я, наконец, начал работать. Для других людей, читающих это: onInterceptTouchEvent можно было бы использовать (но я никогда не понял, как получить координаты экрана вместо координат вида).

Solutions Collecting From Web of "OnTouchListener для всего экрана"

Извините, если я ошибаюсь, но я считаю, что у меня была аналогичная проблема. Мне нужен экран заголовка, на котором была изображена картинка и на изображениях, которые говорят «Нажмите, чтобы продолжить» или что-то подобное. Я немного испортился и обнаружил, что вы можете сделать макет кликабельным.

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

Находится в моем XML-файле для моего макета. Фоновое изображение просто находится в фоновом атрибуте (я понимаю, что вы не используете изображения)

Во всяком случае, еще в моей деятельности

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

И затем я использую оператор switch для обработки этого и кнопок, которые находятся на следующем макете. Здесь, если вам это нужно: использование оператора Switch для обращения к кнопкам

Кажется, это должно работать и с другими макетами, и у меня нет буквально каких-либо взглядов на мой основной макет. (Если сама компоновка не считается одной?)

Ха! Просто понял, что вы сказали, что нашли решение. Глупое время. Я выложу на внеслужебный случай, это помогает кому-то, счастливая кодировка каждого. 🙂

Вы пробовали onInterceptTouchEvent на макете?

Я использовал dispatchTouchEvent для аналогичной проблемы. Вы можете считать его заменой для onTouchEvent , за исключением того, что он всегда отправляет вам событие, даже если оно находится над существующим представлением.

Верните true, если вы обрабатываете событие, иначе обязательно вызовите super.dispatchTouchEvent() и верните его результат.

Что касается получения экранных координат – просто вызовите getRawX getRawX() и getRawY() а не getX() и getY() . Это абсолютные координаты экрана, включая панель действий и все. Если вы хотите перекрестно ссылаться на те, у кого есть представления, getLocationOnScreen – это, пожалуй, самое простое решение.

Сначала прикоснитесь к событию возврата к дочерним представлениям. И если вы определяете для них onClick или onTouch, представление parnt (например, фрагмент) не получит никакого прослушивателя касания. Поэтому, если вы хотите определить swipe-прослушиватель для фрагмента в этой ситуации, вы должны реализовать его в новом классе:

  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 после обнаружения. Это важно, потому что, если мы этого не делаем, некоторые представления ребенка могут получать событие, а оба – для Swipe для фрагмента и 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(); } 

Это немного сложно, но отлично работает 🙂