ViewPager上同时显示多个页面

55

当使用 ViewPager 时,是否有可能同时显示两个页面?我不是在寻找边缘效果,而是想要同时显示两个完整的页面。


我不太确定你在问什么,能否再解释详细一些? - Cody
1
我想让ViewPager并排显示两个可用页面,就像一本书一样。 - Kirill Rakhman
你能否使用两个碎片来实现一页并排的效果?这只是一个想法...不要责怪我... - NIPHIN
8个回答

69

那种技术的问题在于会出现额外的 margin-bottom,导致 ViewPager 下面出现奇怪的空白空间。 - elgui
这会在视图翻页器上添加一些闪烁效果,我仍然可以滑动并看到视图产生奇怪的闪烁。 - Piyush Agarwal

36

请查看我的更新回答:ViewPager每页可以有多个视图吗?

我发现一种更简单的解决方案,即通过为ViewPager指定负边距。我在GitHub上创建了MultiViewPager项目,您可能想要查看:

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中实现了这个功能

Phone example in De Telegraaf KrantTablet example


1
我喜欢你的解决方案。简单而优雅...!谢谢啊。我一直在尝试使用“PageTransformer”来实现这个。 - M-Wajeeh
3
对我而言奏效。你还需要添加setOffScreenPageLimit(2)以将缓存改进为2,以避免在下一个���图时出现滞后。 - Giorgio
1
在之前的笔记中:如果有人被扔出来了,那就是ViewPager.setOffscreenPageLimit(2)。 - fooser

13

你需要在viewpager的适配器上覆盖 getPageWidth() 方法。例如:

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

将那段代码放到你的Adapter中,你就会理解。


3
这看起来非常类似于@Markus-Wörz的答案? - bummi

5

2
欢迎来到StackOverflow!您是否想在您的答案中添加该博客文章的摘录,以便即使链接失效仍然有用? - S.L. Barth
@S.L.Barth 谢谢您的建议。我修改了我的答案。 - kaw

3
你可以通过使用PagerAdapter类中的getPageWidth解决这个问题。
请确定你的JAR文件是否为最新版本。之前ViewPager不支持同时显示多个页面。 public float getPageWidth(){ return 0.4f;(您可以选择它。要每页全屏,应该给1f) }

3

创建你的布局文件: 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",可以使得ViewPager外面的页面也可见。但是现在拖动ViewPager外部没有效果。可以通过从ViewPager容器中获取触摸事件,并将其传递给ViewPager来解决此问题:

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);
      }
 });

MyLayoutBinding是什么?你能给我展示一个完整的例子吗? - Solanki Zeel
谢谢,汉斯。唯一的解决方案帮助我实现了屏幕上多个项目的滑动。 - Taras Vovkovych

-2

我认为使用ViewPager的限制不允许这样的操作。ViewPager只能一次显示一页。您可以尝试通过使用片段,将两个ViewPager片段并排放置,并使用按钮来实现您想要实现的页面翻转,但代码可能会变得非常复杂。

您可以尝试使用ViewFlipper - 在其中可以进行更多自定义(包括动画)。

希望这能帮到您。


-2

这可以在 Viewpager 的Item Layout 中完成。假设您想同时显示两页。

这是Item Layout(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 是最后一页视图页面中项目的数量。


如何使每页显示三个 - M.Yogeshwaran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接