Вложение Android ViewPager, выборка ListItems внутри ListView по горизонтали

У меня есть ViewPager на корневом уровне активности.

Каждая страница пейджера содержит ListFragment (с поддержкой FragmentPagerAdapter).

Некоторые элементы списка также должны содержать ViewPagers, чтобы поддерживать разметку содержимого этих элементов (например, горизонтальную галерею внутри элемента списка).

Как я могу найти пейджеры просмотра? ViewPager -> ListView (на странице) -> ViewPager (внутри элемента списка)

Я могу перемещаться между ListFragments по горизонтали, и я могу перетащить весь список по вертикали, но я не могу прокручивать внутри элементов списка.

Я добавил OnTouchListener в интерьер ViewPager :

 private OnTouchListener mSuppressInterceptListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if( event.getAction() == MotionEvent.ACTION_DOWN && v instanceof ViewGroup ) { ((ViewGroup) v).requestDisallowInterceptTouchEvent(true); } return false; } }; 

Это просто обнаруживает события касания ACTION_DOWN на внутреннем ViewPager и не позволяет внешнему перехватить его. Поскольку он возвращает false, должно быть удалено только событие ACTION_DOWN; Все остальные события будут проигнорированы. Вы можете добавить этого слушателя к каждому элементу, который вы хотите «защитить» от внешней ViewPager , хотя, очевидно, если вы хотите подобрать любое другое поведение прикосновения к этим элементам, вам нужно будет справиться с ними внутри сенсорного прослушивателя и Возможно, реализовать лучшего слушателя.

Поблагодарите @Rodja, который дал мне эту идею в первую очередь.

Хотя это не лучший дизайн взаимодействия, это можно реализовать, перезаписав метод dispatchTouchEvent (MotionEvent ev) активности на уровне корня и используя requestDisallowInterceptTouchEvent (true) на mainPager и текущий ListView, чтобы предотвратить прокрутку. Посмотрите на этот пример:

 @Override public boolean dispatchTouchEvent(MotionEvent ev) { Fragment listFragment = getSupportFragmentManager().findFragmentByTag( "android:switcher:" + R.id.pager + ":" + (mainPager.getCurrentItem())); mainPager.getChildAt(mainPager.getCurrentItem()); if (listFragment == null) return super.dispatchTouchEvent(ev); ViewPager embeddedPager = (ViewPager) listFragment.getView().findViewById(R.id.videopager); if (embeddedPager != null) { int[] position = new int[2]; embeddedPager.getLocationOnScreen(position); if (ev.getY() > position[1] && ev.getY() < position[1] + embeddedPager.getHeight()) { mainPager.requestDisallowInterceptTouchEvent(true); if (embeddedPager.getScrollX() % embeddedPager.getWidth() != 0) { ListView listView = (ListView) listFragment.getView().findViewById( android.R.id.list); listView.requestDisallowInterceptTouchEvent(true); } } } return super.dispatchTouchEvent(ev); } 

Вы не можете вставлять элементы, которым нужны одни и те же жесты, чтобы контролировать их. Поскольку пейджер представления уже фиксирует горизонтальное движение, ваши вложенные элементы не получат его. Вы, вероятно, могли бы сделать много работы, чтобы обойти это, управляя фокусом и т. П., Но в конечном итоге ваше приложение будет запутать пользователей. Его действительно лучше не вставлять элементы, которые будут использовать одно и то же взаимодействие … в этом случае два пейджера просмотра наблюдают за движением стороны в сторону.