Android ViewPager - 在左侧和右侧显示页面预览

Bri*_*yle 99 android android-viewpager

我正在使用Android ViewPager.我想要做的是在左侧和右侧显示页面的预览.我已经看到我可以使用负片pageMargin来显示右侧的预览.

setPageMargin(-100);
Run Code Online (Sandbox Code Playgroud)

无论如何我还能展示左侧的预览吗?它基本上类似于我正在寻找的画廊小部件.

Jij*_*dan 198

要显示左右页面的预览,请设置以下两个值

  1. viewpager.setClipToPadding(false);
  2. viewpager.setPadding(left,0,right,0);

如果在viewpager中需要两个页面之间的空格,则添加

viewpager.setPageMargin(int);
Run Code Online (Sandbox Code Playgroud)

  • 是的我同意你Jiju Induchoodan ..欲了解更多信息,请参阅http://blog.neteril.org/blog/2013/10/14/android-tip-viewpager-with-protruding-children/和http:// stackoverflow .COM /问题/ 13914609/viewpager与 - 先前和下一个页面边界 (2认同)

Roh*_*wal 70

@JijuInduchoodan的答案是完美和有效的.但是,由于我对Android比较新,我花了一段时间才能理解并正确设置它.所以,我发布这个答案以供将来参考,并帮助其他与我相同的人.

if (viewPager == null) 
        {

            // Initializing view pager
            viewPager = (ViewPager) findViewById(R.id.vpLookBook);

            // Disable clip to padding
            viewPager.setClipToPadding(false);
            // set padding manually, the more you set the padding the more you see of prev & next page
            viewPager.setPadding(40, 0, 40, 0);
            // sets a margin b/w individual pages to ensure that there is a gap b/w them
            viewPager.setPageMargin(20);
        }
Run Code Online (Sandbox Code Playgroud)

无需ViewPager's在适配器中为页面设置任何宽度.查看上一页和下一页无需其他代码ViewPager.但是,如果要在每个页面的顶部和底部添加空格,可以将以下代码设置为ViewPager's子页面的父布局.

android:paddingTop="20dp"
android:paddingBottom="20dp"
Run Code Online (Sandbox Code Playgroud)

最终的ViewPager

这将是ViewPager的最终外观.


Ale*_*huk 25

在2017年这样的行为还可以通过使用能够容易地实现RecyclerViewPagerSnapHelper(加入的V7支持库25.1.0版):

在此输入图像描述

前段时间我需要这样的类似viewpager的功能,并准备了一个小型库:

MetalRecyclerPagerView - 您可以在那里找到所有代码和示例.

主要由单个类文件组成:MetalRecyclerViewPager.java(以及两个xmls:attrs.xmlids.xml).

希望它可以帮助某人,并将节省几个小时:)


Kis*_*nki 14

Kotlin + ViewPager2

在此输入图像描述

我参加聚会迟到了,但上述答案对我不起作用。所以我来这里是为了帮助其他仍在寻找答案的人。

  1. 您的 XML:

         <androidx.viewpager2.widget.ViewPager2
         android:id="@+id/newsHomeViewPager"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" />
    
    Run Code Online (Sandbox Code Playgroud)
  2. 你的项目布局根视图应该是这样的:

         <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:paddingStart="@dimen/dp_10"
     xmlns:tools="http://schemas.android.com/tools"
     android:orientation="vertical" />
    
    Run Code Online (Sandbox Code Playgroud)
  3. 您的活动/片段:

在设置 viewpager 适配器之前添加此内容

        newsHomeViewPager.apply {
        clipToPadding = false   // allow full width shown with padding
        clipChildren = false    // allow left/right item is not clipped
        offscreenPageLimit = 2  // make sure left/right item is rendered
    }

    //increase this offset to show more of left/right
    val offsetPx =
        resources.getDimension(R.dimen.dp_30).toInt().dpToPx(resources.displayMetrics)
    newsHomeViewPager.setPadding(0, 0, offsetPx, 0)

    //increase this offset to increase distance between 2 items
    val pageMarginPx =
        resources.getDimension(R.dimen.dp_5).toInt().dpToPx(resources.displayMetrics)
    val marginTransformer = MarginPageTransformer(pageMarginPx)
    newsHomeViewPager.setPageTransformer(marginTransformer)
Run Code Online (Sandbox Code Playgroud)
  1. dp转像素函数:

    fun Int.dpToPx(displayMetrics: DisplayMetrics): Int = (this * displayMetrics.密度).toInt()

一般注意事项:

  1. 我必须只显示下一页,所以在setPadding方法中,我将 0 保留为左侧和offsetPx右侧。因此,如果您也想显示右侧项目,请offsetPx在方法中添加到右侧。setPadding

  2. 我使用了尺寸文件中的 dp,您可以使用自己的。

谢谢您,编码愉快。


44k*_*rma 9

如果有人仍在寻找解决方案,我已经定制了ViewPage来实现它而不使用负边距,在这里找到一个示例项目https://github.com/44kksharma/Android-ViewPager-Carousel-UI 它应该适用于大多数情况但你仍然可以定义页边距 mPager.setPageMargin(margin in pixel);


Alb*_*lvo 8

新的ViewPager2解决方案

如今,您应该考虑使用ViewPager2,它“取代了ViewPager,解决了其前任的大部分难题”

  • 基于RecyclerView
  • RTL(从右到左)布局支持
  • 垂直方向支撑
  • 可靠的片段支持(包括处理对基础片段集合的更改)
  • 数据集更改动画(包括DiffUtil支持)

结果

在此处输入图片说明

代码

在您的活动/片段中,设置ViewPager2:

// MyRecyclerViewAdapter is an standard RecyclerView.Adapter :)
viewPager2.adapter = MyRecyclerViewAdapter() 

// You need to retain one page on each side so that the next and previous items are visible
viewPager2.offscreenPageLimit = 1

// Add a PageTransformer that translates the next and previous items horizontally
// towards the center of the screen, which makes them visible
val nextItemVisiblePx = resources.getDimension(R.dimen.viewpager_next_item_visible)
val currentItemHorizontalMarginPx = resources.getDimension(R.dimen.viewpager_current_item_horizontal_margin)
val pageTranslationX = nextItemVisiblePx + currentItemHorizontalMarginPx
val pageTransformer = ViewPager2.PageTransformer { page: View, position: Float ->
    page.translationX = -pageTranslationX * position
    // Next line scales the item's height. You can remove it if you don't want this effect
    page.scaleY = 1 - (0.25f * abs(position))
    // If you want a fading effect uncomment the next line:
    // page.alpha = 0.25f + (1 - abs(position))
}
viewPager2.setPageTransformer(pageTransformer)

// The ItemDecoration gives the current (centered) item horizontal margin so that
// it doesn't occupy the whole screen width. Without it the items overlap
val itemDecoration = HorizontalMarginItemDecoration(
    context,
    R.dimen.viewpager_current_item_horizontal_margin
)
viewPager2.addItemDecoration(itemDecoration)
Run Code Online (Sandbox Code Playgroud)

添加HorizontalMarginItemDecoration,这是很简单的ItemDecoration

/**
 * Adds margin to the left and right sides of the RecyclerView item.
 * Adapted from /sf/answers/1936481641/
 * @param horizontalMarginInDp the margin resource, in dp.
 */
class HorizontalMarginItemDecoration(context: Context, @DimenRes horizontalMarginInDp: Int) :
    RecyclerView.ItemDecoration() {

    private val horizontalMarginInPx: Int =
        context.resources.getDimension(horizontalMarginInDp).toInt()

    override fun getItemOffsets(
        outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State
    ) {
        outRect.right = horizontalMarginInPx
        outRect.left = horizontalMarginInPx
    }

}
Run Code Online (Sandbox Code Playgroud)

添加尺寸以控制可见的上一个/下一个项目以及当前项目的水平边距:

<dimen name="viewpager_next_item_visible">26dp</dimen>
<dimen name="viewpager_current_item_horizontal_margin">42dp</dimen>
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

最后将添加ViewPager2到您的布局:

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
Run Code Online (Sandbox Code Playgroud)

重要事项:某项ViewPager2必须具有layout_height="match_parent"(否则将引发IllegalStateException),因此您应该执行以下操作:

<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent" <-- this!
    app:cardCornerRadius="8dp"
    app:cardUseCompatPadding="true">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="280dp">

        <!-- ... -->

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>
Run Code Online (Sandbox Code Playgroud)

PageTransformer示例

Google在ViewPager2上添加了一个指南,其中包含2种PageTransformer实现方式,您可以从中获取启发:https : //developer.android.com/training/animation/screen-slide-2

关于新的ViewPager2


sma*_*871 5

您可以在xml文件中执行此操作,只需使用以下代码即可:

 android:clipToPadding="false"
 android:paddingLeft="XX"
 android:paddingRight="XX"
Run Code Online (Sandbox Code Playgroud)

例如:

<androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:paddingLeft="30dp"
        android:paddingRight="30dp" />
Run Code Online (Sandbox Code Playgroud)

注意:如果页面之间需要空格,请将填充/边距设置为子片段

  • 我投票了。兄弟抱歉。这次成功了!!再次投票 (3认同)

Nik*_*dva 5

ViewPager2 的 Kotlin 扩展解决方案


  1. 在您的 Activity 或 Fragment 中单行实现。

    binding.viewpager2.setPreviewBothSide(R.dimen._20sdp,R.dimen._35sdp)
    
    Run Code Online (Sandbox Code Playgroud)
  2. HorizontalMarginItemDecoration.kt在您的项目文件中添加以下代码

    import android.content.Context
    import android.graphics.Rect
    import android.view.View
    import androidx.annotation.DimenRes
    import androidx.recyclerview.widget.RecyclerView
    import androidx.viewpager2.widget.ViewPager2
    
    class HorizontalMarginItemDecoration(context: Context, @DimenRes horizontalMarginInDp: Int) :
        RecyclerView.ItemDecoration() {
        private val horizontalMarginInPx: Int =
            context.resources.getDimension(horizontalMarginInDp).toInt()
    
        override fun getItemOffsets(
            outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State
        ) {
            outRect.right = horizontalMarginInPx
            outRect.left = horizontalMarginInPx
        }
    }
    
    fun ViewPager2.setPreviewBothSide(@DimenRes nextItemVisibleSize: Int,@DimenRes currentItemHorizontalMargin: Int) {
        this.offscreenPageLimit = 1
        val nextItemVisiblePx = resources.getDimension(nextItemVisibleSize)
        val currentItemHorizontalMarginPx = resources.getDimension(currentItemHorizontalMargin)
        val pageTranslationX = nextItemVisiblePx + currentItemHorizontalMarginPx
        val pageTransformer = ViewPager2.PageTransformer { page: View, position: Float ->
            page.translationX = -pageTranslationX * position
            page.scaleY = 1 - (0.25f * kotlin.math.abs(position))
        }
        this.setPageTransformer(pageTransformer)
    
        val itemDecoration = HorizontalMarginItemDecoration(
            context,
            currentItemHorizontalMargin
        )
        this.addItemDecoration(itemDecoration)
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 是的,你得到了这个惊人的输出

    在此输入图像描述

这个答案Albert Vila Calvo 的答案的优化版本


小智 -13

使用此片段适配器和类可以在左右滚动中查看视图分页器。添加必要的类以滚动以查看下一页。

package com.rmn.viewpager;

import java.util.List;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

/**
 * The <code>PagerAdapter</code> serves the fragments when paging.
 * @author mwho
 */
public class PagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments;
    /**
     * @param fm
     * @param fragments
     */
    public PagerAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }
    /* (non-Javadoc)
     * @see android.support.v4.app.FragmentPagerAdapter#getItem(int)
     */
    @Override
    public Fragment getItem(int position) {
        return this.fragments.get(position);
    }

    /* (non-Javadoc)
     * @see android.support.v4.view.PagerAdapter#getCount()
     */
    @Override
    public int getCount() {
        return this.fragments.size();
    }
}



package com.manishkpr.viewpager;


import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class ViewPagerAdapter extends FragmentPagerAdapter {
    private Context _context;

    public ViewPagerAdapter(Context context, FragmentManager fm) {
        super(fm);  
        _context=context;

        }
    @Override
    public Fragment getItem(int position) {
        Fragment f = new Fragment();
        switch(position){
        case 0:
            f=LayoutOne.newInstance(_context);  
            break;
        case 1:
            f=LayoutTwo.newInstance(_context);  
            break;
        }
        return f;
    }
    @Override
    public int getCount() {
        return 2;
    }

}
Run Code Online (Sandbox Code Playgroud)