Может ли ViewPager иметь несколько просмотров на странице? - PullRequest
43 голосов
/ 27 февраля 2012

Попробовав просмотр галереи и горизонтальной прокрутки, я обнаружил, что пейджер просмотра выполняет то, что мне нужно, но при этом не хватает одной мелочи.Может ли View Pager иметь несколько просмотров на странице?

Я знаю, что View Pager показывает только 1 просмотр / страницу за пролистывание.Мне было интересно, могу ли я ограничить ширину своих видов, чтобы мой второй вид, следующий за ним, показывал?

Например: у меня есть 3 вида, и я хочу, чтобы на экране отображались вид 1 и часть вида 2, чтобы пользователь зналесть больше контента, чтобы они могли пролистать для просмотра 2.

|view 1|view 2|view 3|
|screen   |

Ответы [ 7 ]

62 голосов
/ 21 февраля 2013

Я обнаружил, что, возможно, еще более простое решение, указав отрицательное поле для ViewPager.Я создал проект MultiViewPager на GitHub, на который вы можете взглянуть:

https://github.com/Pixplicity/MultiViewPager

Хотя MultiViewPager ожидает дочернее представление для указанияизмерение, принцип вращается вокруг установки поля страницы:

ViewPager.setPageMargin(
    getResources().getDimensionPixelOffset(R.dimen.viewpager_margin));

Затем я указал это измерение в моем dimens.xml:

<dimen name="viewpager_margin">-64dp</dimen>

Чтобы компенсировать перекрывающиеся страницы, представление содержимого каждой страницыимеет противоположное поле:

android:layout_marginLeft="@dimen/viewpager_margin_fix"
android:layout_marginRight="@dimen/viewpager_margin_fix"

Опять в dimens.xml:

<dimen name="viewpager_margin_fix">32dp</dimen>

(Обратите внимание, что размер viewpager_margin_fix равен половине абсолютного размера viewpager_margin.)

Мы реализовали это в приложении к голландской газете De Telegraaf Krant :

Phone example in De Telegraaf KrantTablet example

32 голосов
/ 05 сентября 2012

У Марка Мерфи есть интересное сообщение в блоге, посвященное именно этой проблеме .Хотя я и использовал мое собственное решение в этой теме , стоит взглянуть на код Дэйва Смита, на который Марк ссылается в блоге:

https://gist.github.com/8cbe094bb7a783e37ad1/

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

В итоге вы получите следующее:

Screenshot of Dave Smith's PagerContainer

Он эффективно работает, заключая ViewPager в подкласс FrameLayout, устанавливая его для определенногоразмер и вызов setClipChildren(false).Это запрещает Android обрезать представления, которые выходят за границы ViewPager, и визуально выполняет то, что вы хотите.

В XML это очень просто:

<com.example.pagercontainer.PagerContainer
    android:id="@+id/pager_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#CCC">
    <android.support.v4.view.ViewPager
        android:layout_width="150dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal" />
</com.example.pagercontainer.PagerContainer>

Добавить вНебольшой код для обработки сенсорных событий извне ViewPager и аннулирования дисплея при прокрутке, и все готово.

Как говорится, и хотя в целом это прекрасно работает, я заметил, что естькрайний случай, который не решается с помощью этой довольно простой конструкции: при вызове setCurrentPage() на ViewPager.Единственный способ найти решение этой проблемы - создать подкласс ViewPager, а его функция invalidate() также сделает недействительным PagerContainer.

.
17 голосов
/ 23 августа 2012

Возможно показывать более одной страницы на одном экране. Одним из способов является переопределение метода getPageWidth () в PAgerAdapter. getPageWidth () возвращает число с плавающей точкой между 0 и 1, указывающее, какую ширину Viewpager должна занимать страница. По умолчанию он установлен на 1. Итак, вы можете изменить его на желаемую ширину. Вы можете узнать больше об этом здесь & github project .

15 голосов
/ 17 апреля 2015

Вот как я понял:

<android.support.v4.view.ViewPager
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_gravity="center"
    android:layout_marginBottom="8dp"
    android:clipToPadding="false"
    android:gravity="center"
    android:paddingLeft="36dp"
    android:paddingRight="36dp"/>

и в действии я использую это:

markPager.setPageMargin(64);

надеюсь, это поможет!

9 голосов
/ 16 ноября 2013

У меня была та же проблема с той лишь разницей, что мне нужно было показывать 3 страницы одновременно (предыдущую, текущую и следующую страницы).После очень долгих поисков лучшего решения я думаю, что нашел его.Решение представляет собой сочетание нескольких ответов здесь:

Как указал ответ @Paul Lammertsma - код Дейва Смита в блоге Марка Мерфи является основой для решения.Единственная проблема для меня заключалась в том, что ViewPager был только в верхней части экрана из-за размера, который они дают в XML-файле:

 android:layout_width="150dp"
 android:layout_height="100dp"

, что не годилось для моей цели, так какя искал что-то, что будет распространяться по всему экрану.Поэтому я изменил его, чтобы обернуть содержимое, как вы можете видеть здесь:

  <com.example.nutrino_assignment.PagerContainer
    android:id="@+id/pager_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#CCC">
    <android.support.v4.view.ViewPager
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />
  </com.example.nutrino_assignment.PagerContainer>

Теперь я потерял весь эффект от того, что пытался сделать учебник.С помощью @ andro's answer я смог показать более 1 страницы за раз: ровно 2!Текущий и следующий.Сделал это путем переопределения следующим образом:

        @Override 
    public float getPageWidth(int position) {
        return(0.9f); 
    }

Это было почти то, что мне было нужно ... (хотя я думаю, что этого достаточно для того, что вы просили), но для других, кому может понадобиться что-то вроде того, что яНужно: Для последней части решения я использовал идею в этом ответе , снова @Paul Lammertsma.В коде Дейва Смита вы найдете в методе onCreate следующую строку:

   //A little space between pages
    pager.setPageMargin(15);

, которую я заменил на:

   //A little space between pages
    pager.setPageMargin(-64);

, теперь на первой странице выглядит:

|view 1|view 2|view 3|
|screen   |

в то время как на втором это выглядит так:

|view 1|view 2|view 3|
     |screen    |

Надеюсь, это кому-нибудь поможет!Я потратил на это как 2 дня ... Удачи.

1 голос
/ 23 апреля 2016
viewPager.setPageMargin(-18);// adjust accordingly ,-means less gap

в imageadapter

private class ImagePagerAdapter2 extends PagerAdapter {
    private int[] mImages = new int[] {

            R.drawable.add1,
            R.drawable.add3,
            R.drawable.add4,
            R.drawable.add2,
    };
    @Override
    public float getPageWidth(int position) {
        return .3f;
    }

скорректировать возвращаемое значение ... меньшее означает больше изображения ...... 0,3 означает не менее 3 изображений одновременно.

0 голосов
/ 18 апреля 2015
LayoutParams lp = new LayoutParams(width,height);
viewpager.setLayoutParams(lp);
...