Ответ 1
ОК, одно решение (которое мне все еще не нравится, но работает) заключается в использовании класса TouchInterceptionFrameLayout "(из библиотека, которую я нашел), которая позволит вам решить, когда разрешить прокрутку, а когда нет, и когда она не должна прокручиваться, вы изменяете дополнение (или что вы хотите) макета, который имеет как пейджер-вкладки, так и ViewPager.
Контейнер вкладок viewPager & охватывает всю область и изменяет отступы.
это макет:
<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="wrap_content">
<!-- put upper content here -->
</LinearLayout>
<LinearLayout
android:id="@+id/pagerAndTabsContainer"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/viewPagerSlidingTabsStrip"
android:layout_width="match_parent"
android:background="@color/default_background"
android:layout_height="48dip"/>
<android.support.v4.view.ViewPager
android:background="@color/default_background"
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</com.github.ksoichiro.android.observablescrollview.TouchInterceptionFrameLayout>
Затем вам нужно иметь некоторый код для инициализации (когда выполняется этап макета, и вы можете получить реальные размеры просмотров):
// the upper area height, that can be shrunk to a size of 0 height when needed
mResizeableViewHeight = mHeaderView.getHeight();
// set initial padding if you wish to show the upper area by default
mPagerAndTabsContainer.setPadding(0, mResizeableViewHeight, 0, 0);
prepareViewPager(mViewPager); // set the pages and fragments...
// init the "TouchInterceptionFrameLayout" to handle touch events
mContentView.setScrollInterceptionListener(mInterceptionListener);
в функции "shouldInterceptTouchEvent" от TouchInterceptionFrameLayout.TouchInterceptionListener, вы решаете, когда он должен блокировать касания, а на "onMoveMotionEvent" этого интерфейса вы должны обрабатывать заблокированные штрихи.
для каждого из фрагментов, которые имеют recyclerView, используйте ObservableRecyclerView и вызовите следующие строки:
// get the fragment that shows the screen I've made (with the layout)
Fragment fragment = getTargetFragment();
// let the recyclerView handle filtered touches
mRecyclerView.setTouchInterceptionViewGroup(((IGetContainer) fragment).getContainer());
// if you wish to put animations when you do a touch-up event, this may be handy (or use onUpOrCancelMotionEvent of the "TouchInterceptionListener" too/instead ) :
if (fragment instanceof ObservableScrollViewCallbacks)
mRecyclerView.setScrollViewCallbacks((ObservableScrollViewCallbacks) fragment);
Мне не нравится это решение, потому что оно охватывает весь экран с помощью обложки касаний, потому что это вызывает избыточное перемещение viewPager (и требует установки фона для него), а также потому, что оно немного сложнее по сравнению с что я имел в виду. Он также намного менее плавный, чем работает приложение "Телефон Lollipop", независимо от того, насколько я играю с правилами прокрутки.
Я мог бы заставить TouchInterceptionListener начать обработку события касания только в том случае, если они возникли из RecyclerView, но это делает его еще хуже по сложности.