前のページと次のページの境界を持つViewPager


144

複数ページのビューをデザインしています。前のページと次のページの端を以下のように表示し、2本の指でスワイプしてページを切り替えます。

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

ここでViewPager提案されているように負のページマージンを使用してみましたが、同時に両方ではなく、画面の端の1つだけが表示されます。

または、ビューの一部を画面の外に配置してアニメーション化し、ViewPagerタイプ効果を与える方法はありますか?

どうすればいいですか?よろしくお願いします!


「画面の両方のエッジを同時に表示するのではなく、片方だけを表示します。」ページ0にいて、ページ1の一部しか表示されていませんか?おそらく、円形のポケットベルの例を使用し、ページを常に「中央」の位置に設定する必要があります。この投稿とコメントを参照してください:stackoverflow.com/a/8304474/1851478
logray 12/12/20

回答:


100

この件に関するブログ投稿から自分を引用する:

3番目のアプローチは、評判の高い本「Android Recipes」の共著者であるDave Smithによるものです。彼はまったく異なる方向に進み、一度に複数のページを表示するために子のクリッピングを無効にするカスタムコンテナーを使用しました。

彼が公開したサンプルコードは、実際の動作全体を示しています。彼のコンテナ(com.example.pagercontainer.PagerContainer)はをラップし、それ自体ViewPagerを呼び出しsetClipChildren(false);ます。そのため、ViewPagerが1つの選択されたページにフォーカスしているViewPager場合でも、境界内に座標がある他のページは、内に収まる限り、引き続き表示されますPagerContainer。のサイズViewPagerをより小さいサイズにすることPagerContainerで、ViewPagerはそのページをそのサイズにサイズ変更して、他のページが表示される余地を残すことができます。PagerContainerただし、ViewPager側面に表示されるページを無視して、独自の表示境界でスワイプイベントのみを処理するため、はタッチイベントを少し手助けする必要があります。

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


1
これを使用して、上の画像に示すように前のページと次のページの一部を表示できますが、画像に鋭いエッジを表示したくありません。エッジに向かってぼかしたいのです。私は同じを達成するためにz-indexを使用します
Shruti

2
@Shruti-必要な効果のあるオーバーレイ画像を追加するだけ
Daniel L.

2
私は同じことをしますが、それは最後のアイテムのオーバースクロール効果を無効にします。何かリードはありますか?
Swayam 2014年

1
@CommonsWare:サー、私はあなたの解決策を試しました!それはかなりうまくいきました。オーバースクロールがあります。今唯一の問題は、次のカードが表示され、前のカードは表示されないことです。つまり、ページ2にいる場合、ページ3が表示されますが、ページ1は表示されません。どこで問題があったのでしょうか。
Swayam 2014年

2
@スウェイアム:わからない
CommonsWare 2014年

110

私は同様の解決策を持っています:

ビューページャーで、左右のパディングを設定します(例:20dp)。ビューページャーのページマージンも設定してください(ページャーのパディングの半分など)。また、クリップのパディングを無効にすることを忘れないでください。

tilePager.setPadding(defaultGap, 0, defaultGap, 0);
tilePager.setClipToPadding(false);
tilePager.setPageMargin(halfGap);

2
良い解決策が提供されました。
akash89

最も簡単で最良の方法
HannahCarney 2017年

これは、XDの値を命名考えるための獣はい獣の答えである
silentsudo

1
補足:カスタムビューページャートランスフォーマーでは
機能しません

@voytezトランスのソリューションはありますか?
Alex

76
  1. アイテム全体の左右のパディングを設定します。xmlの例(page_item.xml):

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"/>
    
    <TextView
        android:id="@+id/text1"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
    
    </LinearLayout>
  2. 次に、負のページ余白PageViewを2 *(前のビューのパディング)に設定します。

    int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2,     getResources().getDisplayMetrics());
    mViewPager.setPageMargin(-margin);
  3. オプション。空のエッジを非表示にするには、最初のアイテムの左パディングをゼロ、最後のアイテムの右パディングをゼロに設定します。これは、PageAdapteror Pageフラグメントクラスで行うことができます。


@Sergey、私はあなたのソリューションでこれを機能させることができません、例を投稿できますか?thx
Marckaraujo 2013

12
メモを追加するだけです。このソリューションでは、ページ1からページ2にスライドすると、ページ3がメモリにないため、遅延して表示されます。これを修正するには、追加します-yourViewPager.setOffscreenPageLimit(2);
ホセ・バルボーザ

私は同じことをしますが、それは最後のアイテムのオーバースクロール効果を無効にします。何かリードはありますか?
Swayam 2014年

私もこれを機能させることができないようです...中央クロップに設定されたスケールで画像を使用すると、マージンがランダムに表示されるようです。誰かが共有できる実用的なコード例を持っていますか?
ケニー

2
最初と最後のアイテムに触れる方法は?OnPageListenerでページインデックスをチェックすることによって?
Hardik9850 2017

47

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

viewpager.setClipToPadding(false)
viewpager.setPadding(left,0,right,0)

ビューページャーの2つのページの間にスペースが必要な場合は、viewpager.setPageMargin(int)を追加します。

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


3
これは正解です。これは以前のバージョンのviewpagerでは機能しなかったと思いますが、現在は機能しています。
グレッグエニス2015年

最初のページの左側と最後のページの右側にも同じマージンを追加します。任意の修正
Umesh Aawte 2015

1
短くて明確な答え。
Imran Ahmed、2015

10

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


1

ここからソースコードをダウンロードします(前後のページ境界を含むViewPager

MainActivity.java

package com.deepshikha.viewpager;

import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends FragmentActivity {

    ViewPager pager;
    MyPageAdapter obj_adapter;
    String str_device;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();


    }

    private void init() {
        pager = (ViewPager) findViewById(R.id.viewpager);
        differentDensityAndScreenSize(getApplicationContext());
        List<Fragment> fragments = getFragments();
        pager.setAdapter(obj_adapter);
        pager.setClipToPadding(false);


        if (str_device.equals("normal-hdpi")){
            pager.setPadding(160, 0, 160, 0);
        }else if (str_device.equals("normal-mdpi")){
            pager.setPadding(160, 0, 160, 0);
        }else if (str_device.equals("normal-xhdpi")){
            pager.setPadding(160, 0, 160, 0);
        }else if (str_device.equals("normal-xxhdpi")){
            pager.setPadding(180, 0, 180, 0);
        }else if (str_device.equals("normal-xxxhdpi")){
            pager.setPadding(180, 0, 180, 0);
        }else if (str_device.equals("normal-unknown")){
            pager.setPadding(160, 0, 160, 0);
        }else {

        }

        obj_adapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
        pager.setPageTransformer(true, new ExpandingViewPagerTransformer());
        pager.setAdapter(obj_adapter);
    }

    class MyPageAdapter extends FragmentPagerAdapter {

        private List<Fragment> fragments;

        public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {

            super(fm);

            this.fragments = fragments;

        }

        @Override

        public Fragment getItem(int position) {

            return this.fragments.get(position);

        }

        @Override

        public int getCount() {

            return this.fragments.size();

        }

    }

    private List<Fragment> getFragments() {

        List<Fragment> fList = new ArrayList<Fragment>();

        fList.add(MyFragment.newInstance("Fragment 1",R.drawable.imags));
        fList.add(MyFragment.newInstance("Fragment 2",R.drawable.image1));
        fList.add(MyFragment.newInstance("Fragment 3",R.drawable.image2));
        fList.add(MyFragment.newInstance("Fragment 4",R.drawable.image3));
        fList.add(MyFragment.newInstance("Fragment 5",R.drawable.image4));

        return fList;

    }

    public int differentDensityAndScreenSize(Context context) {
        int value = 20;
        String str = "";
        if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_SMALL) {
            switch (context.getResources().getDisplayMetrics().densityDpi) {
                case DisplayMetrics.DENSITY_LOW:
                    str = "small-ldpi";
                    // Log.e("small 1","small-ldpi");
                    value = 20;
                    break;
                case DisplayMetrics.DENSITY_MEDIUM:
                    str = "small-mdpi";
                    // Log.e("small 1","small-mdpi");
                    value = 20;
                    break;
                case DisplayMetrics.DENSITY_HIGH:
                    str = "small-hdpi";
                    // Log.e("small 1","small-hdpi");
                    value = 20;
                    break;
                case DisplayMetrics.DENSITY_XHIGH:
                    str = "small-xhdpi";
                    // Log.e("small 1","small-xhdpi");
                    value = 20;
                    break;
                case DisplayMetrics.DENSITY_XXHIGH:
                    str = "small-xxhdpi";
                    // Log.e("small 1","small-xxhdpi");
                    value = 20;
                    break;
                case DisplayMetrics.DENSITY_XXXHIGH:
                    str = "small-xxxhdpi";
                    //Log.e("small 1","small-xxxhdpi");
                    value = 20;
                    break;
                case DisplayMetrics.DENSITY_TV:
                    str = "small-tvdpi";
                    // Log.e("small 1","small-tvdpi");
                    value = 20;
                    break;
                default:
                    str = "small-unknown";
                    value = 20;
                    break;
            }

        } else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
            switch (context.getResources().getDisplayMetrics().densityDpi) {
                case DisplayMetrics.DENSITY_LOW:
                    str = "normal-ldpi";
                    // Log.e("normal-ldpi 1","normal-ldpi");
                    str_device = "normal-ldpi";
                    value = 82;
                    break;
                case DisplayMetrics.DENSITY_MEDIUM:
                    // Log.e("normal-mdpi 1","normal-mdpi");
                    str = "normal-mdpi";
                    value = 82;
                    str_device = "normal-mdpi";
                    break;
                case DisplayMetrics.DENSITY_HIGH:
                    // Log.e("normal-hdpi 1","normal-hdpi");
                    str = "normal-hdpi";
                    str_device = "normal-hdpi";
                    value = 82;
                    break;
                case DisplayMetrics.DENSITY_XHIGH:
                    //Log.e("normal-xhdpi 1","normal-xhdpi");
                    str = "normal-xhdpi";
                    str_device = "normal-xhdpi";
                    value = 90;
                    break;
                case DisplayMetrics.DENSITY_XXHIGH:
                    // Log.e("normal-xxhdpi 1","normal-xxhdpi");
                    str = "normal-xxhdpi";
                    str_device = "normal-xxhdpi";
                    value = 96;
                    break;
                case DisplayMetrics.DENSITY_XXXHIGH:
                    //Log.e("normal-xxxhdpi","normal-xxxhdpi");
                    str = "normal-xxxhdpi";
                    str_device = "normal-xxxhdpi";
                    value = 96;
                    break;
                case DisplayMetrics.DENSITY_TV:
                    //Log.e("DENSITY_TV 1","normal-mdpi");
                    str = "normal-tvdpi";
                    str_device = "normal-tvmdpi";
                    value = 96;
                    break;
                default:
                    // Log.e("normal-unknown","normal-unknown");
                    str = "normal-unknown";
                    str_device = "normal-unknown";
                    value = 82;
                    break;
            }
        } else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
            switch (context.getResources().getDisplayMetrics().densityDpi) {
                case DisplayMetrics.DENSITY_LOW:
                    str = "large-ldpi";
                    // Log.e("large-ldpi 1","normal-ldpi");
                    value = 78;
                    break;
                case DisplayMetrics.DENSITY_MEDIUM:
                    str = "large-mdpi";
                    //Log.e("large-ldpi 1","normal-mdpi");
                    value = 78;
                    break;
                case DisplayMetrics.DENSITY_HIGH:
                    //Log.e("large-ldpi 1","normal-hdpi");
                    str = "large-hdpi";
                    value = 78;
                    break;
                case DisplayMetrics.DENSITY_XHIGH:
                    // Log.e("large-ldpi 1","normal-xhdpi");
                    str = "large-xhdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_XXHIGH:
                    //Log.e("large-ldpi 1","normal-xxhdpi");
                    str = "large-xxhdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_XXXHIGH:
                    // Log.e("large-ldpi 1","normal-xxxhdpi");
                    str = "large-xxxhdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_TV:
                    //Log.e("large-ldpi 1","normal-tvdpi");
                    str = "large-tvdpi";
                    value = 125;
                    break;
                default:
                    str = "large-unknown";
                    value = 78;
                    break;
            }

        } else if ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
            switch (context.getResources().getDisplayMetrics().densityDpi) {
                case DisplayMetrics.DENSITY_LOW:
                    // Log.e("large-ldpi 1","normal-ldpi");
                    str = "xlarge-ldpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_MEDIUM:
                    // Log.e("large-ldpi 1","normal-mdpi");
                    str = "xlarge-mdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_HIGH:
                    //Log.e("large-ldpi 1","normal-hdpi");
                    str = "xlarge-hdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_XHIGH:
                    // Log.e("large-ldpi 1","normal-hdpi");
                    str = "xlarge-xhdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_XXHIGH:
                    // Log.e("large-ldpi 1","normal-xxhdpi");
                    str = "xlarge-xxhdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_XXXHIGH:
                    // Log.e("large-ldpi 1","normal-xxxhdpi");
                    str = "xlarge-xxxhdpi";
                    value = 125;
                    break;
                case DisplayMetrics.DENSITY_TV:
                    //Log.e("large-ldpi 1","normal-tvdpi");
                    str = "xlarge-tvdpi";
                    value = 125;
                    break;
                default:
                    str = "xlarge-unknown";
                    value = 125;
                    break;
            }
        }

        return value;
    }
}

1
このコードは適切に機能せず、左側のページが右側より少し大きく表示されます
Chirag Joshi

1

いつか前、私は、このような機能を必要とし、使用しています小さなライブラリ用意しRecyclerViewPagerSnapHelper古典の代わりに(V7サポートライブラリのバージョン25.1.0で追加を)ViewPager

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

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

それが誰かを助けることを願っています:)

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