Несколько страниц одновременно на ViewPager

Есть ли возможность отображать две страницы одновременно при использовании ViewPager? Я ищу не краевой эффект, а две полные страницы одновременно.


person Kirill Rakhman    schedule 12.01.2012    source источник
comment
Я не совсем понимаю, о чем вы спрашиваете... не могли бы вы объяснить немного больше?   -  person Cody    schedule 12.01.2012
comment
Я хочу, чтобы ViewPager отображал две доступные страницы рядом, как книгу.   -  person Kirill Rakhman    schedule 12.01.2012
comment
Не могли бы вы использовать два фрагмента для достижения побочного эффекта страниц? это просто идея... не вини меня.....   -  person NIPHIN    schedule 24.09.2014


Ответы (8)


Пожалуйста, ознакомьтесь с методом getPageWidth в соответствующем разделе PagerAdapter. Переопределите его и верните, например. 0.8f чтобы все дочерние страницы занимали только 80% ширины ViewPager.

Дополнительная информация: http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getPageWidth(int)

person Markus Wörz    schedule 30.08.2012
comment
проблема с этой техникой заключается в том, что появляется дополнительное поле margin-bottom, добавляющее странное пустое пространство под Viewpager. - person elgui; 22.10.2013
comment
Это добавляет некоторый эффект мерцания на пейджере просмотра, я все еще могу провести пальцем и вижу, что представления делают странное мерцание. - person pyus13; 02.11.2017

Посмотрите мой более актуальный ответ здесь: Может ли ViewPager иметь несколько представлений на странице?

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

https://github.com/Pixplicity/MultiViewPager

Хотя этот вопрос конкретно требует решения без краевого эффекта, некоторые ответы здесь предлагают обходной путь от CommonsWare, например, предложение kaw.

Существуют различные проблемы с сенсорным управлением и аппаратным ускорением с этим конкретным решением. Более простое и элегантное решение, на мой взгляд, — указать отрицательное поле для ViewPager:

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< /эм>:

Пример телефона в De Telegraaf KrantПример планшета

person Paul Lammertsma    schedule 20.01.2014
comment
Мне понравилось ваше решение. Просто и элегантно... ! Спасибо чувак. Я пытался добиться этого, используя PageTransformer. - person M-WaJeEh; 25.02.2014
comment
работал на меня. Вам также необходимо добавить setOffScreenPageLimit(2), чтобы улучшить кэширование до 2, чтобы избежать отставания при втором следующем просмотре. - person Giorgio; 11.05.2014
comment
В предыдущем примечании: это ViewPager.setOffscreenPageLimit(2) на случай, если кого-то выкинут. - person fooser; 09.07.2014

Вы должны переопределить метод getPageWidth() в адаптере viewpager. Например:

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

Попробуйте этот код в своем адаптере, и тогда вы поймете.

person flagg327    schedule 14.09.2014
comment
Это очень похоже на ответ @Markus-Wörz? - person bummi; 14.09.2014

См. эту запись в блоге.
Техника PagerContainer решила мою проблему.

EDIT:
Я нашел тот же ответ.
Как перейти с Галереи на HorizontalScrollView и ViewPager?

person kaw    schedule 19.10.2012
comment
Добро пожаловать в StackOverflow! Хотели бы вы добавить отрывок из этого сообщения в блоге к своему ответу, чтобы он по-прежнему был полезен, если ссылка исчезнет? - person S.L. Barth; 19.10.2012
comment
@S.L.Barth Спасибо за совет. Я изменил свой ответ. - person kaw; 19.10.2012

создайте файл макета: my_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
    android:id="@+id/pager_container"
    android:layout_width="match_parent"
    android:layout_height="240dp"
    android:clipChildren="false">

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="200dp"
        android:clipToPadding="false"
        android:layout_height="200dp"
        android:layout_marginLeft="70dp"
        android:layout_marginRight="70dp"
        android:layout_gravity="center" />
</FrameLayout>
</layout>

Viewpager примерно такой же маленький, как вы хотите, чтобы ваши страницы были. С android:clipToPadding="false" страницы за пределами пейджера также видны. Но теперь перетаскивание за пределы пейджера не имеет никакого эффекта. Это можно исправить, выбирая касания из пейджера-контейнера и передавая их пейджеру:

MyLayoutBinding binding = DataBindingUtil.<MyLayoutBinding>inflate(layoutInflater, R.layout.my_layout, parent, false)
binding.pager.setOffscreenPageLimit(3);
binding.pager.setPageMargin(15);
binding.pagerContainer.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
           return chatCollectionLayoutBinding.pager.onTouchEvent(event);
      }
 });
person Hans    schedule 02.02.2017
comment
Что такое MyLayoutBinding, можете ли вы показать мне полный пример - person Solanki Zeel; 03.09.2019
comment
Спасибо, Ханс. Единственное решение помогло мне реализовать несколько элементов на экране с помощью скользящего - person Taras Vovkovych; 24.03.2020

Вы можете решить эту проблему, используя getPageWidth в классе PagerAdapter.

Убедитесь, что ваш JAR обновлен. Поскольку ранее ViewPager не поддерживал несколько страниц одновременно.

открытый поплавок getPageWidth () {

return 0.4f;(Вы можете выбрать его. Для полного экрана на странице вы должны указать 1f) }

person Community    schedule 25.11.2012

Я не думаю, что это возможно с ограничениями View Pager. Это позволяет пользователю просматривать только одну страницу за раз. Возможно, вы сможете что-то решить с использованием фрагментов и иметь 2 фрагмента ViewPager рядом и использовать кнопки для разработки перелистывания страниц, которое вы хотите реализовать, но код может стать очень сложным.

Вы можете попробовать что-то вроде ViewFlipper, где вы можете сделать гораздо больше настроек (включая анимацию).

Надеюсь это поможет.

person aimango    schedule 02.02.2012

Это можно сделать в Макет элемента на странице просмотра. Предположим, вам нужны две страницы за раз.

Это Макет элемента (photo_slider_item.xml):

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" style="@style/photosSliderItem">
        <ImageView android:id="@id/photoBox1" style="@style/photoBox"/>
        <ImageView android:id="@id/photoBox2" style="@style/photoBox"/>
    </LinearLayout>

И в вашем PagerAdapter:

@Override
public View instantiateItem(ViewGroup container, int position){
    View sliderItem = LayoutInflater.from(container.getContext()).inflate(photo_slider_item, container, false);
    ImageView photoBox1 = (ImageView) sliderItem.findViewById(R.id.photoBox1);
    ImageView photoBox2 = (ImageView) sliderItem.findViewById(R.id.photoBox2);
    photoBox1.setImageResource(photosIds[position]);
    if(position < photosIds.length-1){
        photoBox2.setImageResource(photosIds[position+1]);
    } else {photoBox2.setImageResource(photosIds[0]);}
    container.addView(sliderItem);
    return sliderItem;
}

Отредактированная версия для более чем двух элементов

если вам нужно более двух элементов, сначала добавьте их в LinearLayout, а затем используйте следующий алгоритм:

photoBox1.setImageResource(photosIds[position]);
if(position < photosIds.length-i-1){
   photoBox2.setImageResource(photosIds[position+1]);
   photoBox3.setImageResource(photosIds[position+2]);
   .
   .
   .
   photoBox(i).setImageResource(photosIds[position+i-1]);
} else if(position < photosIds.length-i-2){
   photoBox2.setImageResource(photosIds[position+1]);
   photoBox3.setImageResource(photosIds[position+2]);
   .
   .
   .
   photoBox(i-1).setImageResource(photosIds[position+i-2]);
   photoBox(i).setImageResource(photosIds[0]);
} . . . else if(position < photosIds.length-1){
   photoBox2.setImageResource(photosIds[position+1]);
   photoBox3.setImageResource(photosIds[0]);
   photoBox4.setImageResource(photosIds[1]);
   .
   .
   .
   photoBox(i-1).setImageResource(photosIds[i-2-2]);
   photoBox(i).setImageResource(photosIds[i-2-1]);
} else {
    photoBox2.setImageResource(photosIds[0]);
    photoBox3.setImageResource(photosIds[1]);
    .
    .
    .
    photoBox(i-1).setImageResource(photosIds[i-1-2]);
    photoBox(i).setImageResource(photosIds[i-1-1]);
}

i : количество ваших элементов

[i-2-2] : цифра 2 в середине – это количество элементов на последней странице просмотра.

person Arash    schedule 09.03.2017
comment
как сделать по три на странице - person M.Yogeshwaran; 15.07.2018