Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

В то время как это не лучший дизайн взаимодействия, это можно реализовать, перезаписав метод 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);
}

Ответ 3

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