Android ViewPager - Pokaż podgląd strony po lewej i po prawej stronie


107

Używam Androida ViewPager. Chcę tylko pokazać podgląd strony po lewej i po prawej stronie. Widziałem, gdzie mogę użyć negatywu, pageMarginaby wyświetlić podgląd prawej strony.

setPageMargin(-100);

Czy w ogóle mogę wyświetlić podgląd lewej strony? Jest to w zasadzie coś podobnego do widżetu galerii, którego szukam.


Dobre pytanie! Niedawno sprawdziłem źródło i czuję, że nie ma lepszego sposobu, jeśli nie chcesz modyfikować kodu src. Czy setPageMargin(-100)działa poprawnie?
Macarse

GalleryView wykona pracę lepiej, chyba że używasz ViewPger z fragmentami.
Ali AlNoaimi

Udało mi się to zrobić za pomocą widoku galerii. tak samo jak viewpager w żaden sposób. nie wiem, dlaczego galeria jest przestarzała
WillingLearner

To pytanie zostało od tego czasu obszernie omówione w [post tutaj] [1] [1]: stackoverflow.com/questions/13914609/…
Ben Pearson

używam Vierpagera z fragmentami, więc czy mogę zastosować to samo podejście?
asliyanage

Odpowiedzi:


206

Aby wyświetlić podgląd lewej i prawej strony, ustaw następujące dwie wartości

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

Jeśli potrzebujesz odstępu między dwiema stronami w podglądzie, dodaj

viewpager.setPageMargin(int);

2
Tak, zgadzam się z tobą Jiju Induchoodan .. Aby uzyskać więcej informacji, odwiedź blog.neteril.org/blog/2013/10/14/ ... i stackoverflow.com/questions/13914609/ ...
Sripathi

Fajnie, to takie proste :) Czy jest możliwość zmiany rozmiaru podglądu dla prawego i lewego rozmiaru na przełączanych stronach widoku pagera? Na przykład - jeśli fragment jest nieostry - jego skala będzie wynosić ~ 0,8, ale gdy przeciągniemy go do środka - skala wzrośnie do 1, a poprzedni fragment z widoku środkowego zmieni skalę na 0,8, wychodząc poza ekran?
iamthevoid

To działa! Ale kiedy próbuję powiększyć układ środkowy, powiększa się do góry i do dołu. Lewa i prawa strona nie są widoczne ze względu na wypełnienie. Zobacz pytanie stackoverflow.com/questions/52710076/…
Anooj Krishnan G

nie działa z przeglądarką 2
hamiid reza Gholami

73

Odpowiedź @JijuInduchoodan jest doskonała i działa. Jednak ponieważ jestem stosunkowo nowy w Androidzie, zajęło mi trochę czasu, aby zrozumieć i ustawić go prawidłowo. Dlatego zamieszczam tę odpowiedź do wykorzystania w przyszłości i pomagam każdemu, kto jest w tym samym miejscu co ja.

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

Nie ma potrzeby ustawiania żadnej szerokości ViewPager'sstrony w adapterze. Nie jest wymagany żaden dodatkowy kod, aby wyświetlić poprzednią i następną stronę ViewPager. Jeśli jednak chcesz dodać puste miejsce na górze i na dole każdej strony, możesz ustawić następujący kod na ViewPager'sukład nadrzędny strony podrzędnej.

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

Final ViewPager

To będzie ostateczny wygląd ViewPagera.


62

Rozwiązanie z nowym ViewPager2

W dzisiejszych czasach powinieneś rozważyć użycie ViewPager2, który „zastępuje ViewPager, rozwiązując większość problemów jego poprzednika” :

  • Na podstawie RecyclerView
  • Obsługa układu RTL (od prawej do lewej)
  • Wsparcie orientacji pionowej
  • Niezawodna obsługa fragmentów (w tym obsługa zmian w podstawowej kolekcji fragmentów)
  • Animacje zmiany zbioru danych (w tym DiffUtilwsparcie)

Wynik

wprowadź opis obrazu tutaj

Kod

W swojej aktywności / fragmencie skonfiguruj 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)

Dodaj HorizontalMarginItemDecoration, co jest trywialne 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
    }

}

Dodaj wymiary, które kontrolują, jaka część poprzedniego / następnego elementu jest widoczna, oraz poziomy margines bieżącego elementu:

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

wprowadź opis obrazu tutaj

Na koniec dodaj ViewPager2do swojego układu:

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

Jedna ważna rzecz: ViewPager2element musi mieć layout_height="match_parent"(w przeciwnym razie rzuca wyjątek IllegalStateException), więc powinieneś zrobić coś takiego:

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

Przykłady PageTransformera

Google dodał przewodnik po ViewPager2, który ma 2 PageTransformerimplementacje, których możesz użyć jako inspiracji: https://developer.android.com/training/animation/screen-slide-2

O nowym ViewPager2


Ten sam problem na urządzeniach oreo, dopełnienie początku i końca działa zgodnie z oczekiwaniami na innych urządzeniach, ale oreo po ViewPager2. PageTransformer rozwiązał problem, wyściółki są nadal takie same i musiałem dodaćviewpager.setPageTransformer { page, position -> page.translationX = -1 * position }
zgr

Muszę lekko przesunąć stronę widoku, aby uzyskać ten efekt
Muhammad Saqib

nieważne, zapomniałem dodać tę linię setOffscreenPageLimit(1):)
Muhammad Saqib

To najlepsze rozwiązanie, jakie kiedykolwiek znalazłem. Działa doskonale, ale tak, NIE ZAPOMNIJ ustawić szerokość i wysokość elementu ViewPager2 na MATCH_PARENT.
khushbu

26

W 2017 r takiego działania dodatkowo może być łatwo osiągnięty za pomocą RecyclerViewz PagerSnapHelper (wersja 25.1.0 dodano biblioteki nośnej V7) 

wprowadź opis obrazu tutaj

Jakiś czas temu potrzebowałem funkcji przypominającej przeglądarkę i przygotowałem małą bibliotekę:

MetalRecyclerPagerView - możesz tam znaleźć cały kod wraz z przykładami.

Głównie składa się z jednego pliku klasy: MetalRecyclerViewPager.java (oraz dwóch plików xml: attrs.xml i ids.xml ).

Mam nadzieję, że to komuś pomoże i pozwoli zaoszczędzić kilka godzin :)


Poza tematem, ponieważ czasami potrzebny jest tylko pager, ale dobrze wiedzieć! Dzięki za udostępnienie!
sud007

To jest niesamowite. Miałem już mnóstwo kodu pomocniczego RecyclerView. Po prostu dodaję proste new PagerSnapHelper().attachToRecyclerView(recyclerView)i mam przyciąganie stron.
Steve


7

Możesz to zrobić w pliku xml, po prostu użyj poniższego kodu:

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

Na przykład:

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

Uwaga: jeśli potrzebujesz odstępu między stronami, ustaw dopełnienie / marginesy na fragmenty podrzędne


3
Głosowałem w dół. przepraszam bracie. Tym razem zadziałało !! Głosowano ponownie
shikhar bansal

1

Dla tych, którzy mają problemy z wyświetlaniem tego na różnych ekranach,

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



-10

Użyj tego adaptera fragmentu i klasy, aby wyświetlić przeglądarkę w przewijaniu w lewo i w prawo. Dodaj niezbędne klasy, aby przewijać, aby wyświetlić następne strony.

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

}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.