Я нашел вопрос ниже: Android: FragmentActivity внутри FragmentActivity (ScrollView в NavigationBar). Однако этот мой вопрос касается того, как использовать транзакции для отображения фрагментов, а также включить безопасное обнаружение жестов смахивания. Примечание. В опубликованном мною ответе есть ссылка (здесь также есть эффективный способ отображения фрагментов в контейнере с использованием транзакций, включая два сценария). Пожалуйста, посмотри на это. Я пробовал несколько вещей в этом отношении, но используя фрагмент, поддерживающий ViewPager, а не вложенный:
Подробности: https://moqups.com/[email protected]/lc0ZOERO/p:a5d7b55eb
- Отключено смахивание по умолчанию с использованием onTouchEvent и onInterceptTouchEvent с использованием настраиваемого ViewPager.
- Объявленный FragmentStatePagerAdapter снабжен списком фрагментов, каждый из которых отображается на каждой вкладке.
- Объявите фрагменты в main_layout main_activity, рядом с которым находится ViewPager. Идея состоит в том, чтобы отображать activity_fragments, когда нажимается кнопка на ViewPager_fragment и когда пользователь нажимает кнопку возврата, тогда ViewPager_fragment по умолчанию снова отображается с использованием транзакций заднего стека при добавлении и выталкивании их на BackPressed активности. Поэтому я также поддерживаю свой собственный задний стек, чтобы отображать / скрывать activity_fragments, когда задний стек выводит транзакцию.
Теперь я хочу выполнить третий пункт выше, используя жесты смахивания только вправо [слева направо].
Для этого я использовал GestureListener и SimpleOnGestureListener, а также OnTouchEvent активности.
Проблема, с которой я сталкиваюсь:
Этот жест работает с той частью экрана активности, которая находится под фрагментом и частью действия. Я хочу, чтобы жест работал
- В области фрагмента, в макете которой есть несколько представлений.
- Только в направлении влево-вправо.
- Только от activity_fragment до фрагмента вкладки ViewPager, чтобы вести себя как навигация по истории, как это уже было сделано в реализации onBakPressed / onKeyDown с использованием всплывающих окон заднего стека и моего настраиваемого заднего стека.
Я попробовал следующий класс и изменил фрагмент своей деятельности в таких макетах.
Слушатель My Gesture and Touch расширен макетом кадра:
public class OnSwipeTouchListener extends FrameLayout {
private final GestureDetector gestureDetector;
private static final String TAG = "OnSwipeTouchListener";
private Context context;
public OnSwipeTouchListener(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
gestureDetector = new GestureDetector(context, new GestureListener());
setClickable(true);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(motionEvent);
return super.onTouchEvent(event);
}
private final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
boolean result = false;
try {
float diffY = e2.getY() - e1.getY();
float diffX = e2.getX() - e1.getX();
if (Math.abs(diffX) > Math.abs(diffY)) {
if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
if (diffX > 0) {
onSwipeRight();
} else {
onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
onSwipeBottom();
} else {
onSwipeTop();
}
}
}
} catch (Exception exception) {
//see that e1 is null
}
return result;
}
}
public void onSwipeRight() {
///manage my back stack history here.
}
public void onSwipeLeft() {
}
public void onSwipeTop() {
}
public void onSwipeBottom() {
}
}
а затем измените макеты фреймов на эту ссылку на класс:
<path.to.my.package.OnSwipeTouchListener
android:id="@+id/activity_frag_frame_layout1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="invisible" >
<fragment
android:id="@+id/activity_frag1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="path.to.my.package.fragments.Activity_Frag1"
android:tag="act_frag1" />
</path.to.my.package.OnSwipeTouchListener>
Мне это мало помогло, так что должно помочь вам в поиске решения. В одном из фрагментов перестал работать searchView, и ни один клик не работает. Если вы получили то, чего я хочу достичь, пожалуйста, помогите в этом отношении.
Обновление 1: возврат true как в onTouchEvent, так и в onInterceptTouchEvent имеет желаемый эффект, но он блокирует щелчки во фрагментах, где есть SearchView, ни один щелчок не работает в представленных интерактивных представлениях. Только свайп работает. Обновление: в моем последнем: я также полностью отказался от использования стеков транзакций назад, потому что я полагаюсь на свой собственный задний стек, в котором я поддерживаю историю навигации для всех вкладок. Для этого я использую методы setCurrentTab и onTabSelected, предоставленные ViewPager и FragmentStatePagerAdapter.
Обновление 2: это сложно реализовать: проверьте, какие события нужно перехватить, а какие передать дочерним представлениям: http://developer.android.com/training/gestures/viewgroup.html
Обновление 3:
В моем макете для активности есть пейджер просмотра, а в макете каждого кадра под ним есть один фрагмент.
Когда вы запускаете приложение, ViewPager показывает фрагмент на первой вкладке.
Когда нажимается кнопка на этом фрагменте, отображается один из фрагментов в макете фрейма под пейджером просмотра и добавляется в мой собственный задний стек.
При нажатии клавиши возврата этот фрагмент снова скрывается, чтобы показать фрагмент вкладки в пейджере просмотра. Все вышеперечисленное выполнено. Только я хочу, чтобы срабатывал жест смахивания слева направо, и я обнаружил, что могу делать это, перехватывая события касания. Но он этого совсем не делает. Когда я возвращаю true, работает только жест смахивания, в противном случае это действие отменяется и щелчки по этому фрагменту работают.