Android ViewPager-左右にページのプレビューを表示


107

Androidを使用していますViewPager。私がしたいことは、ページのプレビューを左右両方に表示することです。ネガpageMarginを使用して右側のプレビューを表示できる場所を見てきました。

setPageMargin(-100);

とにかく左側のプレビューも表示できますか?基本的には、私が探しているギャラリーウィジェットに似ています。


良い質問!私は最近ソースをチェックしましたが、srcコードを変更したくない場合は、これ以上の方法はないと感じています。いsetPageMargin(-100)、正しく仕事を?
Macarse

フラグメントでViewPgerを使用している場合を除いて、GalleryViewはより適切に機能します。
Ali AlNoaimi 2012

ギャラリービューを使用してこれを行うことができました。何らかの点でviewpagerと同じです。ギャラリーが廃止された理由がわからない
WillingLearner

この質問は以降広くこちらの記事]でカバーされている[1] [1]:stackoverflow.com/questions/13914609/...
ベン・ピアソン

Vierpagerをフラグメントで使用しています。同じアプローチを使用できますか?
asliyanage 2015年

回答:


206

左右のページのプレビューを表示するには、次の2つの値を設定します

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

ビューページャーの2つのページの間にスペースが必要な場合は、次を追加します

viewpager.setPageMargin(int);

2
はい、私はより多くの情報について..あなたJiju Induchoodanに同意参照してくださいblog.neteril.org/blog/2013/10/14/...stackoverflow.com/questions/13914609/...
Sripathi

クール、それはとても簡単です:)ビューページャーのページ切り替えで右と左のサイズのプレビューのサイズを変更することは可能ですか?たとえば、フラグメントがフォーカスから外れている場合、そのスケールは〜0.8ですが、中央にドラッグすると、スケールが1に増加し、中央のビューからの前のフラグメントは、画面から出るときにスケールが0.8に変更されますか?
iamthevoid 2016年

これは機能しています!しかし、中央のレイアウトをズームしようとすると、上と下にズームします。パディングのため、左右は見えません。質問stackoverflow.com/questions/52710076/…を
Anooj Krishnan G '10

はviewpager 2で動作していません
hamiid reza Gholami

73

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

ViewPager'sアダプターのページに幅を設定する必要はありません。の前のページと次のページを表示するために追加のコードは必要ありませんViewPager。ただし、各ページの上部と下部に空白スペースを追加する場合は、次のコードをViewPager's子ページの親レイアウトに設定できます。

android:paddingTop="20dp"
android:paddingBottom="20dp"

最終的なViewPager

これがViewPagerの最終的な外観になります。


62

新しい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)

追加HorizontalMarginItemDecoration些細です、ItemDecoration

/**
 * Adds margin to the left and right sides of the RecyclerView item.
 * Adapted from https://stackoverflow.com/a/27664023/4034572
 * @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
    }

}

前/次のアイテムをどれだけ表示するかを制御する寸法と、現在のアイテムの水平マージンを追加します。

<dimen name="viewpager_next_item_visible">26dp</dimen>
<dimen name="viewpager_current_item_horizontal_margin">42dp</dimen>

ここに画像の説明を入力してください

最後にをViewPager2レイアウトに追加します。

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewPager"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

重要なことの1つ: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>

PageTransformerの例

GoogleはPageTransformer、インスピレーションとして使用できる2つの実装があるViewPager2のガイドを追加しました:https : //developer.android.com/training/animation/screen-slide-2

新しいViewPager2について


oreoデバイスで同じ問題、パディングの開始と終了は他のデバイスで期待どおりに機能しますが、ViewPager2の後のoreo。PageTransformerが問題を解決しました。パディングは同じで、追加する必要がありましたviewpager.setPageTransformer { page, position -> page.translationX = -1 * position }
zgr

この効果を得るには、ビューページャーのページを少し移動する必要があります
Muhammad Saqib

気にしないで、私はこの行を追加するのを忘れましたsetOffscreenPageLimit(1):)
Muhammad Saqib

これは私が見つけた最高のソリューションです。これは完全に機能しますが、ViewPager2の項目の幅と高さをMATCH_PARENTに設定することを忘れないでください。
khushbu

26

2017では、このような動作RecyclerViewPagerSnapHelper(v7サポートライブラリのバージョン25.1.0で追加)を使用することで簡単に実現できます。:

ここに画像の説明を入力してください

いつか私はそのようなviewpagerのような機能が必要で、小さなライブラリを用意しました:

MetalRecyclerPagerView-すべてのコードとその例を見つけることができます。

主に単一のクラスファイルであるMetalRecyclerViewPager.java(および2つのxml:attrs.xmlids.xml)で構成されています。

それが誰かを助け、数時間を節約することを願っています:)


時々ページャーしか必要とされないので、トピックから外れていますが、知っておくといいですね 共有してくれてありがとう!
sud007 2017年

これは素晴らしいです。すでに大量のRecyclerViewヘルパーコードがありました。単純なものnew PagerSnapHelper().attachToRecyclerView(recyclerView)を追加するだけで、ページスナップができます。
Steve

9

誰かがまだ解決策を探している場合、負のマージンを使用せずにそれを実現するようにViewPageをカスタマイズしました。サンプルプロジェクトをここで見つけますhttps://github.com/44kksharma/Android-ViewPager-Carousel-UI ほとんどの場合に機能するはずですが、あなたはそれでもページマージンを定義できます mPager.setPageMargin(margin in pixel);


7

これはxmlファイルで行うことができます。以下のコードを使用してください。

 android:clipToPadding="false"
 android:paddingLeft="XX"
 android:paddingRight="XX"

例えば:

<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" />

注:ページ間にスペースが必要な場合は、パディング/マージンを子フラグメントに設定してください


3
私は反対票を投じました。ごめんね。今回はうまくいきました!再度賛成
シカールバンサル

1

これを別の画面で表示するのに苦労している人のために、

mPager.setClipToPadding(false);
DisplayMetrics displayMetrics = new DisplayMetrics();
self.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int width = displayMetrics.widthPixels;
int paddingToSet = width/4; //set this ratio according to how much of the next and previos screen you want to show.
mPager.setPadding(paddingToSet,0,paddingToSet,0);


0

ビューページャーにゼロパディングを設定しない場合、ビューページャーのエッジ効果の配置がめちゃくちゃになることに注意してください。これはビューページャーのバグです。ここを参照してください:ビューページャーエッジ効果のバグ

android:overScrollMode="never"ビューページャーに設定してエッジ効果を無効にするか、EdgeEffectクラスのわずかに変更されたバージョンでバグを修正することができます:ViewPagerEdgeEffect fix


-10

このフラグメントアダプターとクラスを使用して、viewpagerを左右にスクロールします。スクロールして次のページを表示するために必要なクラスを追加します。

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

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.