Вопрос по android, nested, android-viewpager, listview – Вложение Android ViewPager, смахивание ListItems внутри ListView по горизонтали

12

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

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

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

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

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

Ваш Ответ

3   ответа
11

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, который первым дал мне идею.

Вот это да. Гораздо чище. Спасибо!
Просто не могу поверить, как легко это работает. Большое спасибо, Андрей и Родя!
Безусловно самое простое решение.
Я сталкиваюсь с подобной проблемой, это позволяет мне проводить пальцем влево и вправо. Что делать, если я также хочу включить на кран, а затем открыть выбранный вид?
Вы можете написать свой собственный прослушиватель кликов, прослушивая ACTION_DOWN, а затем ACTION_UP; если сумма всех событий ACTION_MOVE между ними меньше, чем системаtouch slop (см. ниже) назовите это щелчком.developer.android.com/reference/android/view/… имеет константы для касания, долгого нажатия и вообще всего, что вам нужно.
0

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

3

его можно реализовать, перезаписавdispatchTouchEvent(MotionEvent ev) метод корневого уровня Activity и использование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);
}
Спасибо за это. Я немного изменил эту идею, чтобы позволить вам поместить код в другое место, чемActivity#dispatchTouchEvent(MotionEvent) функция, но идея, которую я использовал, была в основном ваша :)

Похожие вопросы