ViewPager dengan batas halaman sebelumnya dan berikutnya


144

Saya mendesain tampilan dengan beberapa halaman. Saya ingin tepi halaman sebelumnya dan berikutnya ditampilkan seperti di bawah ini dan menerapkan sapuan 2 jari untuk beralih di antara halaman.

masukkan deskripsi gambar di sini

Saya mencoba menggunakan ViewPagerdengan margin halaman negatif seperti yang disarankan di sini, tetapi itu hanya menunjukkan salah satu ujung di layar, tidak keduanya secara bersamaan.

Atau, apakah ada cara saya dapat memposisikan bagian dari tampilan saya di luar layar dan kemudian menghidupkannya sehingga memberikan ViewPagerefek tipe.

Bagaimana saya harus melakukannya? Terima kasih!


"Hanya menunjukkan salah satu ujung di layar, bukan keduanya secara bersamaan." Apakah Anda di halaman 0 dan Anda hanya melihat bagian dari halaman 1? Mungkin Anda perlu menggunakan pager melingkar, contoh dan kemudian atur halaman Anda selalu ke posisi "tengah". Lihat postingan ini dan komentarnya: stackoverflow.com/a/8304474/1851478
logray

Jawaban:


100

Mengutip diri sendiri dari posting blog tentang hal ini :

Pendekatan ketiga datang dari Dave Smith, rekan penulis buku Android Recipes yang dianggap baik. Dia pergi ke arah yang sangat berbeda, menggunakan wadah khusus yang memungkinkan anak-anak terpotong untuk menunjukkan lebih dari satu halaman sekaligus.

Nya diterbitkan kode contoh menunjukkan semuanya dalam tindakan. Wadahnya ( com.example.pagercontainer.PagerContainer) membungkus ViewPagerdan memanggilnya setClipChildren(false);sendiri, jadi meskipun ViewPagerterfokus pada satu halaman yang dipilih, halaman lain yang memiliki koordinat di luar ViewPagerbatas masih terlihat, asalkan sesuai dengan PagerContainer. Dengan ukuran yang ViewPagerlebih kecil dari yang PagerContainer, ViewPagerukuran kaleng halaman ke ukuran itu, meninggalkan ruang untuk halaman lain untuk dilihat. PagerContainerNamun, perlu sedikit membantu dengan acara sentuh, karena ViewPagerhanya akan menangani acara gesek pada batas yang terlihat sendiri, mengabaikan halaman apa pun yang terlihat di samping.

masukkan deskripsi gambar di sini


1
dengan menggunakan ini, saya dapat menunjukkan bagian dari halaman sebelumnya dan berikutnya seperti yang ditunjukkan pada gambar di atas, tapi sekarang saya tidak ingin menunjukkan tepi tajam pada gambar. Saya ingin mereka kabur ke tepi .. tolong bantu saya bagaimana bisa saya menggunakan z-index untuk mencapai hal yang sama
Shruti

2
@Shruti - cukup tambahkan gambar hamparan dengan efek yang Anda inginkan
Daniel L.

2
Saya melakukan hal yang sama tetapi menonaktifkan efek over-scroll untuk item terakhir. Adakah petunjuk tentang itu?
Swayam

1
@ CommonsWare: Pak, saya mencoba solusi Anda! Itu bekerja dengan cukup baik. Overcroll ada di sana. Satu-satunya masalah sekarang adalah bahwa kartu berikutnya menunjukkan, tetapi bukan kartu sebelumnya. Yaitu, jika saya di halaman 2, saya bisa melihat halaman 3 mengintip keluar, tetapi bukan halaman 1. Di mana saya bisa salah?
Swayam

2
@Swayam: Saya tidak tahu.
CommonsWare

110

Saya punya solusi serupa:

Pada viewpager atur padding kiri dan kanan, mis. 20dp. Juga mengatur margin halaman pada viewpager, misalnya setengah dari pager padding. Dan jangan lupa untuk menonaktifkan clip padding.

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

2
Solusi bagus disediakan.
akash89

cara termudah dan terbaik
HannahCarney

Ini adalah jawaban beast yes beast untuk mempertimbangkan nilai penamaan xd
silentsudo

1
catatan: ini tidak akan bekerja dengan transformator pager tampilan kustom
voytez

@voytez ada solusi untuk transformator?
Alex

76
  1. Atur padding kiri dan kanan untuk seluruh tampilan item. Contoh 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. Kemudian setel margin halaman negatif PageViewmenjadi sama dengan 2 * (tampilan sebelumnya)

    int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2,     getResources().getDisplayMetrics());
    mViewPager.setPageMargin(-margin);
  3. Pilihan. Atur nol padding kiri untuk item pertama dan nol padding kanan untuk item terakhir untuk menyembunyikan tepi kosong. Anda dapat melakukan ini di PageAdapteratau Pagekelas fragmen.


@Sergey, saya tidak bisa melakukan ini dengan solusi Anda, bisakah Anda memposting contoh? thx
Marckaraujo

12
hanya menambahkan catatan: dengan solusi ini ketika Anda meluncur dari halaman 1 ke halaman 2, halaman 3 tidak ada dalam memori, sehingga akan muncul dengan penundaan. untuk memperbaikinya tambahkan saja - yourViewPager.setOffscreenPageLimit (2);
José Barbosa

Saya melakukan hal yang sama tetapi menonaktifkan efek over-scroll untuk item terakhir. Adakah petunjuk tentang itu?
Swayam

Sepertinya saya tidak bisa mendapatkan ini berfungsi baik ... margin tampaknya ditampilkan secara acak jika saya menggunakan gambar w / skala yang diatur ke tengah memotong. Adakah yang punya contoh kode kerja yang bisa mereka bagikan?
kenyee

2
Bagaimana cara menyentuh item pertama dan terakhir? Dengan memeriksa indeks halaman di OnPageListener?
Hardik9850

47

Untuk menampilkan pratinjau halaman kiri dan kanan, atur dua nilai berikut

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

Jika Anda membutuhkan ruang antara dua halaman di viewpager kemudian tambahkan viewpager.setPageMargin (int)

Android ViewPager - Tampilkan pratinjau halaman di kiri dan kanan


3
Ini harus jawaban yang benar. Saya pikir mungkin ini tidak bekerja di versi viewpager sebelumnya tetapi berfungsi sekarang.
Greg Ennis

Ini menambahkan margin yang sama di sisi kiri halaman pertama dan kanan juga. Perbaikan apa pun
Umesh Aawte

1
Jawaban singkat dan lebih jelas.
Imran Ahmed


1

Unduh kode sumber dari sini ( ViewPager dengan batas halaman sebelumnya dan berikutnya )

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
Kode ini tidak berfungsi sebagaimana mestinya, ini menunjukkan halaman sisi kiri sedikit lebih besar dari sisi kanan
Chirag Joshi

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.