Önceki ve sonraki sayfa sınırlarına sahip ViewPager


145

Birden çok sayfalı bir görünüm tasarlıyorum. Önceki ve sonraki sayfaların kenarlarının aşağıdaki gibi gösterilmesini ve sayfalar arasında geçiş yapmak için 2 parmağınızla kaydırmayı uygulamak istiyorum.

resim açıklamasını buraya girin

BuradaViewPager önerildiği gibi negatif sayfa kenar boşluğu ile kullanmayı denedim ama bu sadece ekranda kenarlardan birini gösteriyor, aynı anda değil.

Alternatif olarak, görünümümün bir kısmını ekran dışına konumlandırmanın ve daha sonra ona bir ViewPagertür efekti vererek canlandırmanın herhangi bir yolu var mı ?

Nasıl başlamalıyım? Teşekkürler !


"sadece ekranın kenarlarından birini gösterir, ikisini aynı anda göstermez." Sayfa 0'da mısınız ve sayfa 1'in yalnızca bir bölümünü görüyor musunuz? Örneğin, dairesel bir çağrı cihazı kullanmanız ve ardından sayfanızı her zaman "orta" konuma ayarlamanız gerekir. Bu
gönderiye

Yanıtlar:


100

Bu konuyla ilgili bir blog yayınından alıntı yapıyorum :

Üçüncü yaklaşım, saygın Android Tarifler kitabının ortak yazarı Dave Smith'ten geliyor. Çocukların kırpmasını bir kerede birden fazla sayfa göstermesini engelleyen özel bir kap kullanarak çok farklı bir yöne gitti.

Onun yayınlanan örnek kod gösterileri eylem hepsi. Kapsayıcısı ( com.example.pagercontainer.PagerContainer) kendisini seçer ViewPagerve setClipChildren(false);kendisini çağırır ; bu nedenle ViewPager, seçili bir sayfaya odaklanmış olsa da , ViewPagersınırların ötesinde koordinatları olan diğer sayfalar, içine sığdığı sürece hala görülebilir PagerContainer. Boyutlandırma ile ViewPagerdaha küçük olması PagerContainer, ViewPagerdiğer sayfalar için oda bırakarak kutu boyutu bu boyuta onun sayfaları görülecek. PagerContainerBununla birlikte, dokunma olaylarıyla biraz yardımcı olması gerekir, çünkü ViewPagerkaydırma olaylarını yalnızca kendi görünür sınırlarında işleyebilir ve kenarlarda görünen sayfaları yok sayar.

resim açıklamasını buraya girin


1
Bunu kullanarak, yukarıdaki resimde gösterildiği gibi önceki ve sonraki sayfanın bir kısmını gösterebiliyorum, ancak şimdi görüntülerde keskin kenarlar göstermek istemiyorum. Ben aynı ulaşmak için z-endeksi kullanın
Shruti

2
@Shruti - İstediğiniz efektle bir kaplama resmi ekleyin
Daniel L.

2
Aynı şeyi yapıyorum ama son öğe için fazla kaydırma efektini devre dışı bırakıyor. Herhangi bir ipucu var mı?
Swayam

1
@CommonsWare: Efendim, çözümünüzü denedim! Oldukça iyi çalıştı. Fazla kaydırma orada. Şimdi tek sorun, bir sonraki kartın gösterilmesi, ancak önceki kartın gösterilmemesidir. Yani, eğer sayfa 2'deysem, sayfa 3'ü görüyorum, ancak sayfa 1'i göremiyorum. Nerede yanlış gidebilirdim?
Swayam

2
@Swayam: Hiçbir fikrim yok.
CommonsWare

111

Benzer bir çözüm var:

Vizörde sol ve sağ dolguları ayarlayın, örneğin 20dp. Ayrıca sayfa kenar boşluğunu vizörde, örneğin çağrı cihazı dolgusunun yarısı gibi ayarlayınız. Klip dolguyu devre dışı bırakmayı da unutmayın.

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

2
İyi çözüm sağlandı.
akash89

en kolay ve en iyi yol
HannahCarney

Bu adlandırma değerlerini dikkate almak için canavar evet canavar cevap xd
silentsudo

1
yan not: Bu özel bir görünüm çağrı transformatörü ile çalışmaz
voytez

@voytez trafo için herhangi bir çözüm var mı?
Alex

76
  1. Tüm öğe görünümü için sol ve sağ dolguları ayarlayın. Örnek 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. Ardından negatif sayfa kenar boşluğunu PageView2 * değerine ayarlayın (önceki görünüm dolgusu)

    int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2,     getResources().getDisplayMetrics());
    mViewPager.setPageMargin(-margin);
  3. İsteğe bağlı. Boş kenarları gizlemek için ilk öğe için sıfır sol dolgu ve son öğe için sıfır sağ dolgu ayarlayın. Bunu PageAdapterveya Pagefragment sınıfında yapabilirsiniz.


@Sergey, bu çözümü sizin çözümünüzle yapamıyorum, bir örnek gönderebilir misiniz? thx
Marckaraujo

12
sadece bir not eklemek: bu çözümle sayfa 1'den sayfa 2'ye kaydırdığınızda sayfa 3 bellekte değil, bu yüzden gecikmeli olarak görünecektir. bunu düzeltmek için sadece ekleyin - yourViewPager.setOffscreenPageLimit (2);
José Barbosa

Aynı şeyi yapıyorum ama son öğe için fazla kaydırma efektini devre dışı bırakıyor. Herhangi bir ipucu var mı?
Swayam

Bunu da işe yaramıyor gibi görünmüyorum ... kırpma merkezi ayarlamak için ölçek w / görüntüleri kullanırsanız kenar boşlukları rastgele görüntüleniyor gibi görünüyor. Herkesin paylaşabileceği bir çalışma kodu örneği var mı?
kenyee

2
İlk ve son öğeye nasıl dokunulur? OnPageListener'daki sayfa dizinini kontrol ederek?
Hardik9850

48

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

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

Viewpager'da iki sayfa arasında boşluğa ihtiyacınız varsa viewpager.setPageMargin (int) öğesini ekleyin.

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


3
Bu doğru cevap olmalı. Sanırım bu önceki viewpager sürümlerinde işe yaramadı ama şimdi çalışıyor.
Greg Ennis

Son sayfanın ilk ve sağ tarafına da aynı kenar boşluğu ekliyor. Herhangi bir düzeltme
Umesh Aawte

1
Kısa ve daha net cevap.
İmran Ahmed


1

Kaynak kodu buradan indirin ( Önceki ve sonraki sayfa sınırlarıyla 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
Bu kod düzgün çalışmıyor, sol sayfa biraz sağdan daha büyük gösteriliyor
Chirag Joshi

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.