Android ViewPager - Sayfanın önizlemesini solda ve sağda göster


107

Android kullanıyorum ViewPager. Yapmak istediğim, sayfanın önizlemesini hem solda hem de sağda göstermek. pageMarginSağ tarafın önizlemesini göstermek için bir negatifi nerede kullanabileceğimi gördüm .

setPageMargin(-100);

Sol tarafın da önizlemesini gösterebileceğim bir şey var mı? Temelde aradığım galeri widget'ına benzer bir şey.


İyi soru! Yakın zamanda kaynağı kontrol ettim ve src kodunu değiştirmek istemiyorsanız daha iyi bir yol olmadığını düşünüyorum. Does setPageMargin(-100)doğru çalışıyor mu?
Macarse

ViewPger'ı fragmanlarla kullanmıyorsanız, GalleryView işi daha iyi yapacaktır.
Ali AlNoaimi 01

Bunu galeri görünümünü kullanarak yapabildim. herhangi bir şekilde görüntüleyici ile aynı. galerinin neden kullanımdan kaldırıldığını bilmiyorum
WillingLearner

Bu soru, o zamandan beri [buradaki postayla] [1] [1]: stackoverflow.com/questions/13914609/…
Ben Pearson

Parçalarla Vierpager kullanıyorum.Peki aynı yaklaşımı kullanabilir miyim?
asliyanage

Yanıtlar:


206

Sol ve sağ sayfaların önizlemesini göstermek için aşağıdaki iki değeri ayarlayın

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

Görüntü sayfasındaki iki sayfa arasında boşluğa ihtiyacınız varsa,

viewpager.setPageMargin(int);

2
Evet sana katılıyorum Jiju Induchoodan .. Daha fazla bilgi için lütfen blog.neteril.org/blog/2013/10/14/… ve stackoverflow.com/questions/13914609/…
Sripathi

Harika, çok basit :) Önizlemeleri görüntüleme sayfasının geçiş sayfalarında sağ ve sol boyutlarda yeniden boyutlandırmak mümkün mü? Örneğin - eğer odak dışında bir parça varsa - ölçeği ~ 0,8 olacak, ancak onu merkeze sürüklediğimizde ölçek 1'e yükselecek ve merkezden önceki parça ekrandan çıkarken ölçeği 0.8'e değiştirecek?
iamthevoid

Bu çalışıyor! Ancak merkez düzeni yakınlaştırmaya çalıştığımda, yukarı ve aşağı doğru yakınlaştırıyor. Sol ve sağ, dolgu nedeniyle görünmüyor. Lütfen stackoverflow.com/questions/52710076/…
Anooj Krishnan G

viewpager 2 ile çalışmıyor
hamiid reza Gholami

73

@JijuInduchoodan'ın cevabı mükemmel ve çalışıyor. Ancak, Android'de nispeten yeni olduğum için, onu anlamam ve doğru şekilde ayarlamam biraz zaman aldı. Bu yüzden, bu cevabı ileride başvurmak üzere gönderiyorum ve benimle aynı yerde olan herkese yardım ediyorum.

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'sBağdaştırıcıda sayfanın herhangi bir genişliğini ayarlamanıza gerek yoktur . İçinde önceki ve sonraki sayfayı görmek için ek kod gerekmez ViewPager. Bununla birlikte, her sayfanın üstüne ve altına boşluk eklemek isterseniz, aşağıdaki kodu ViewPager'salt sayfanın üst düzenine ayarlayabilirsiniz.

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

Son GörünümPager

Bu, ViewPager'ın son görünümü olacaktır.


62

Yeni ViewPager2 ile çözüm

Günümüzde "ViewPager'ın yerini alan ve selefinin sorunlu noktalarının çoğunu ele alan " ViewPager2'yi kullanmayı düşünmelisiniz :

  • RecyclerView'e göre
  • RTL (sağdan sola) düzen desteği
  • Dikey yönlendirme desteği
  • Güvenilir Fragment desteği (temeldeki Fragment koleksiyonundaki değişiklikleri işleme dahil)
  • Veri kümesi değişikliği animasyonları ( DiffUtildestek dahil )

Sonuç

görüntü açıklamasını buraya girin

Kod

Aktivitenizde / Parçanızda, ViewPager2'yi kurun:

// 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Önemsiz olan, ekleyin 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
    }

}

Önceki / sonraki öğenin ne kadarının görünür olacağını kontrol eden boyutları ve geçerli öğe yatay kenar boşluğunu ekleyin:

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

görüntü açıklamasını buraya girin

Son olarak ViewPager2düzeninize ekleyin :

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

Önemli bir şey: bir ViewPager2öğenin sahip olması gerekir layout_height="match_parent"(aksi takdirde IllegalStateException oluşturur), bu nedenle aşağıdaki gibi bir şey yapmalısınız:

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

Google, ViewPager2'ye PageTransformerilham kaynağı olarak kullanabileceğiniz 2 uygulamaya sahip bir kılavuz ekledi : https://developer.android.com/training/animation/screen-slide-2

Yeni ViewPager2 hakkında


Oreo cihazlarda aynı sorun, diğer cihazlarda beklendiği gibi doldurma başlangıcı ve bitişi çalışıyor, ancak ViewPager2'den sonra oreo. PageTransformer sorunu çözdü, viewpager.setPageTransformer { page, position -> page.translationX = -1 * position }
dolgular

Bu etkiyi elde etmek için görüntülü çağrı cihazının sayfasını biraz hareket ettirmem gerekiyor
Muhammed Saqib

boşver, bu satırı eklemeyi unuttum setOffscreenPageLimit(1):)
Muhammad Saqib

Bulduğum en iyi çözüm bu. Mükemmel çalışıyor ancak evet ViewPager2'nin Öğe genişliğini, yüksekliğini MATCH_PARENT olarak ayarlamayı UNUTMAYIN.
khushbu

26

İlave olarak kullanılarak kolayca elde edilebilir 2017 gibi davranışta RecyclerViewile PagerSnapHelper (v7 destek kütüphanesinin sürüm 25.1.0 ilave edildi): 

görüntü açıklamasını buraya girin

Bir süre önce, böyle bir görüntüleyici benzeri özelliğe ihtiyacım vardı ve küçük bir kitaplık hazırladım:

MetalRecyclerPagerView - tüm kodu örneklerle birlikte burada bulabilirsiniz.

Esas olarak tek bir sınıf dosyasından oluşur: MetalRecyclerViewPager.java (ve iki xml : attrs.xml ve ids.xml ).

Umarım birine yardımcı olur ve birkaç saat kazandırır :)


Konu dışı, çünkü bazen yalnızca çağrı cihazına ihtiyaç duyulur, ancak bilmek güzel! Paylaşım için teşekkürler!
sud007

Bu harika. Zaten tonlarca RecyclerView yardımcı kodum vardı. Sadece basit bir ekleme new PagerSnapHelper().attachToRecyclerView(recyclerView)ve sayfa yakalamam var.
Steve


7

Bunu xml dosyasında yapabilirsiniz, sadece aşağıdaki kodu kullanın:

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

Örneğin:

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

Not: Sayfalar arasında boşluğa ihtiyacınız varsa, alt parçalara dolgu / kenar boşluğu ayarlayın


3
Olumsuz oy verdim. üzgünüm kardeşim. Bu sefer işe yaradı !! Tekrar oy verildi
shikhar bansal

1

Bunu farklı ekranlarda görmek isteyenler için,

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

Bir görüntüleyiciye sıfır dolgusu ayarlamadığınızda, görüntüleyicinin kenar efekti yerleşiminin hatalı olduğunu unutmayın, bu, görüntüleyicinin bir hatasıdır, buraya bakın: görüntüleyici edgeeffect hatası

Görüntüleyiciye ayarlayarak kenar efektini devre dışı bırakabilir android:overScrollMode="never"veya hatayı EdgeEffect sınıfının biraz değiştirilmiş bir sürümüyle düzeltebilirsiniz : ViewPagerEdgeEffect fix


-10

Viewpager'ı sola ve sağa kaydırmak için bu parça adaptörünü ve sınıfı kullanın. Sonraki sayfaları görüntülemek için kaydırmak için gerekli sınıfları ekleyin.

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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.