Android ViewPager - Tampilkan pratinjau halaman di kiri dan kanan

107

Saya menggunakan Android ViewPager. Yang ingin saya lakukan adalah menampilkan pratinjau halaman di kiri dan kanan. Saya telah melihat di mana saya dapat menggunakan negatif pageMarginuntuk menunjukkan pratinjau dari sisi kanan.

setPageMargin(-100);

Apakah ada juga yang bisa saya tampilkan pratinjau sisi kiri juga? Ini pada dasarnya sesuatu yang mirip dengan widget galeri yang saya cari.

Brian Boyle
sumber
Pertanyaan bagus! Saya baru-baru ini memeriksa sumbernya dan saya merasa tidak ada cara yang lebih baik jika Anda tidak ingin mengubah kode src. Apakah setPageMargin(-100)berfungsi dengan benar?
Macarse
GalleryView akan melakukan pekerjaan dengan lebih baik, kecuali jika Anda menggunakan ViewPger dengan fragmen.
Ali AlNoaimi
Saya bisa melakukan ini menggunakan tampilan galeri. sama seperti viewpager dengan cara apapun. tidak tahu mengapa galeri tidak digunakan lagi
WillingLearner
Pertanyaan ini telah dibahas secara ekstensif di [posting di sini] [1] [1]: stackoverflow.com/questions/13914609/…
Ben Pearson
saya menggunakan Vierpager dengan fragmen. Jadi, apakah saya dapat menggunakan pendekatan yang sama?
asliyanage

Jawaban:

206

Untuk menampilkan pratinjau halaman kiri dan kanan atur dua nilai berikut

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

Jika Anda membutuhkan spasi antara dua halaman di viewpager, tambahkan

viewpager.setPageMargin(int);
Jiju Induchoodan
sumber
2
Ya, saya setuju dengan Anda Jiju Induchoodan .. Untuk info lebih lanjut silakan lihat blog.neteril.org/blog/2013/10/14/… dan stackoverflow.com/questions/13914609/…
Sripathi
Keren, ini sangat sederhana :) Apakah ada kemungkinan untuk mengubah ukuran pratinjau pada ukuran kanan dan kiri pada halaman saklar tampilan pager? Misalnya - jika fragmen tidak fokus - skalanya akan menjadi ~ 0,8, tetapi ketika kita menyeretnya ke tengah - skala akan meningkat menjadi 1, dan fragmen sebelumnya dari tampilan tengah akan mengubah skala menjadi 0,8 saat keluar dari layar?
iamthevoid
Ini bekerja! Tetapi ketika saya mencoba untuk memperbesar tata letak tengah, tampilannya ke atas dan ke bawah. Kiri dan kanan tidak terlihat karena bantalannya. Silakan lihat pertanyaan stackoverflow.com/questions/52710076/…
Anooj Krishnan G
tidak berfungsi dengan viewpager 2
hamiid reza Gholami
73

Jawaban oleh @JijuInduchoodan sempurna dan berhasil. Namun, karena saya relatif baru mengenal Android, butuh beberapa saat untuk memahami & mengaturnya dengan benar. Jadi, saya memposting jawaban ini untuk referensi di masa mendatang dan membantu orang lain yang memiliki posisi yang sama dengan saya.

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

Tidak perlu menyetel lebar apa pun ke ViewPager'shalaman di adaptor. Tidak ada kode tambahan yang diperlukan untuk melihat halaman sebelumnya & berikutnya di ViewPager. Namun, jika Anda ingin menambahkan ruang kosong di bagian atas & bawah setiap halaman, Anda dapat menyetel kode berikut ke ViewPager'stata letak induk halaman anak.

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

ViewPager akhir

Ini akan menjadi tampilan terakhir ViewPager.

Rohan Kandwal
sumber
62

Solusi dengan ViewPager2 baru

Saat ini Anda harus mempertimbangkan untuk menggunakan ViewPager2 yang "menggantikan ViewPager, menangani sebagian besar masalah pendahulunya" :

  • Berdasarkan RecyclerView
  • Dukungan tata letak RTL (kanan-ke-kiri)
  • Dukungan orientasi vertikal
  • Dukungan Fragmen yang andal (termasuk menangani perubahan pada koleksi Fragmen yang mendasarinya)
  • Animasi perubahan set data (termasuk DiffUtildukungan)

Hasil

masukkan deskripsi gambar di sini

Kode

Di Aktivitas / Fragmen Anda, siapkan 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)

Tambahkan HorizontalMarginItemDecoration, yang sepele 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
    }

}

Tambahkan dimensi yang mengontrol seberapa banyak item sebelumnya / berikutnya terlihat, dan margin horizontal item saat ini:

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

masukkan deskripsi gambar di sini

Terakhir tambahkan ViewPager2ke tata letak Anda:

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

Satu hal penting: ViewPager2item harus memiliki layout_height="match_parent"(jika tidak maka akan melempar IllegalStateException), jadi Anda harus melakukan sesuatu seperti:

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

Contoh PageTransformer

Google telah menambahkan panduan di ViewPager2 yang memiliki 2 PageTransformerimplementasi yang dapat Anda gunakan sebagai inspirasi: https://developer.android.com/training/animation/screen-slide-2

Tentang ViewPager2 baru

Albert Vila Calvo
sumber
Masalah yang sama pada perangkat oreo, padding start dan end berfungsi seperti yang diharapkan pada perangkat lain kecuali oreo setelah ViewPager2. PageTransformer menyelesaikan masalah, paddings masih sama dan saya harus menambahkanviewpager.setPageTransformer { page, position -> page.translationX = -1 * position }
zgr
Saya harus sedikit memindahkan tampilan halaman halaman untuk mendapatkan efek ini
Muhammad Saqib
sudahlah, saya lupa menambahkan baris ini setOffscreenPageLimit(1):)
Muhammad Saqib
Ini adalah solusi terbaik yang pernah saya temukan. Ini bekerja dengan sempurna tapi ya JANGAN LUPA untuk mengatur lebar Item ViewPager2, tinggi ke MATCH_PARENT.
khushbu
26

Pada tahun 2017 perilaku tersebut juga dapat dengan mudah dicapai dengan menggunakan RecyclerViewdengan PagerSnapHelper (ditambahkan pada versi 25.1.0 dukungan v7 perpustakaan): 

masukkan deskripsi gambar di sini

Beberapa waktu yang lalu saya membutuhkan fitur seperti viewpager dan menyiapkan perpustakaan kecil:

MetalRecyclerPagerView - Anda dapat menemukan semua kode beserta contoh di sana.

Terutama terdiri dari satu file kelas: MetalRecyclerViewPager.java (dan dua xmls: attrs.xml dan ids.xml ).

Semoga ini membantu seseorang dan akan menghemat beberapa jam :)

Alexander Bilchuk
sumber
Di luar topik, karena terkadang hanya pager yang dibutuhkan tapi Senang mengetahuinya! Terima kasih telah berbagi!
sud007
Ini luar biasa. Saya sudah memiliki banyak sekali kode pembantu RecyclerView. Hanya menambahkan yang sederhana new PagerSnapHelper().attachToRecyclerView(recyclerView)dan saya memiliki gertakan halaman.
Steve
9

jika seseorang masih mencari solusi, saya telah menyesuaikan ViewPage untuk mencapainya tanpa menggunakan margin negatif, temukan proyek sampel di sini https://github.com/44kksharma/Android-ViewPager-Carousel-UI seharusnya berfungsi dalam banyak kasus tetapi Anda masih dapat menentukan margin halaman dengan mPager.setPageMargin(margin in pixel);

44kksharma
sumber
7

Anda dapat melakukan ini dalam file xml, cukup gunakan kode di bawah ini:

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

Sebagai contoh:

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

Catatan: Jika Anda membutuhkan spasi antar halaman, setel padding / margin ke fragmen turunan

sma6871.dll
sumber
3
Saya tidak menyukai. maaf bro. Kali ini berhasil !! Suara positif lagi
shikhar bansal
1

Bagi mereka yang kesulitan menampilkannya di layar berbeda,

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);
Saurabh Verma
sumber
0

Perhatikan bahwa saat menyetel none zero paddings ke viewpager, penempatan edgeeffect viewpager menjadi kacau, ini adalah bug viewpager, lihat di sini: viewpager edgeeffect bug

Anda bisa menonaktifkan efek tepi dengan menyetel android:overScrollMode="never"ke viewpager, atau Anda bisa memperbaiki bug dengan versi kelas EdgeEffect yang sedikit dimodifikasi: ViewPagerEdgeEffect fix

ssynhtn
sumber
-10

Gunakan adaptor fragmen dan kelas ini untuk melihat viewpager di scroll kiri dan kanan. Tambahkan kelas yang diperlukan untuk menggulir guna melihat halaman berikutnya.

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

}
Veerababu Medisetti
sumber