이전 및 다음 페이지 경계가있는 ViewPager


144

여러 페이지가있는보기를 디자인하고 있습니다. 이전 페이지와 다음 페이지의 가장자리를 아래와 같이 표시하고 페이지 간을 전환하기 위해 두 손가락 스 와이프를 구현하고 싶습니다.

여기에 이미지 설명을 입력하십시오

여기에ViewPager 제안 된 것처럼 네거티브 페이지 여백을 사용하려고했지만 동시에 화면 가장자리 중 하나만 표시합니다.

또는 내보기의 일부를 화면 외부에 배치하고 애니메이션을 적용하여 ViewPager유형 효과를 줄 수있는 방법이 있습니까?

어떻게해야합니까? 감사 !


"화면의 가장자리 중 하나만 표시하며 둘 다 동시에 표시되지는 않습니다." 0 페이지에 있고 1 페이지의 일부만 보입니까? 예를 들어, 원형 호출기를 사용하고 페이지를 항상 "중간"위치로 설정해야합니다. 이 게시물과 의견을 참조하십시오 : stackoverflow.com/a/8304474/1851478
logray

답변:


100

이 주제에 대한 블로그 게시물 에서 인용 :

세 번째 방법은 유명한 저서 인 Android Recipes의 공동 저자 인 Dave Smith가 제공합니다. 그는 한 번에 여러 페이지를 표시하기 위해 어린이 클리핑을 비활성화하는 사용자 지정 컨테이너를 사용하여 매우 다른 방향으로 나아갔습니다.

그의 공개 된 샘플 코드 는 모든 것을 실제로 보여줍니다. 그의 컨테이너 ( com.example.pagercontainer.PagerContainer)는를 감싸고 자체적으로 ViewPager호출 setClipChildren(false);하므로 ViewPager선택한 페이지에 초점이 맞춰져 있지만 ViewPager범위를 넘어 좌표가있는 다른 페이지 는 여전히 볼 수 있습니다 PagerContainer. 크기를 조정함으로써 ViewPager댄 작게 PagerContainerViewPager다른 페이지에 대 한 방을 떠날 캔 크기가 크기의 페이지는 볼 수 있습니다. PagerContainer그러나 터치 이벤트와 관련하여 약간의 도움이 필요합니다 ViewPager. 측면에서 볼 수있는 페이지는 무시하고 자체 가시 범위의 스 와이프 이벤트 만 처리합니다.

여기에 이미지 설명을 입력하십시오


1
이것을 사용하여 위의 이미지와 같이 이전 페이지와 다음 페이지의 일부를 표시 할 수는 있지만 이제 이미지에 날카로운 가장자리를 표시하고 싶지 않습니다. 나는
그것을

2
@Shruti-원하는 효과로 오버레이 이미지 추가
Daniel L.

2
나는 똑같이하지만 마지막 항목에 대한 오버 스크롤 효과를 비활성화합니다. 그것에 대한 리드?
Swayam

1
@CommonsWare : 선생님, 솔루션을 시도했습니다! 꽤 잘 작동했습니다. 오버 스크롤이 있습니다. 문제는 다음 카드가 표시되지만 이전 카드는 표시되지 않는다는 것입니다. 즉, 2 페이지에있는 경우 3 페이지는 엿볼 수 있지만 1 페이지는 볼 수 없습니다. 어디에서 잘못되었을 수 있습니까?
Swayam

2
@Swayam : 나는 모른다.
CommonsWare

110

비슷한 해결책이 있습니다.

viewpager에서 왼쪽 및 오른쪽 패딩을 설정하십시오 (예 : 20dp). 또한 호출기 패딩의 절반과 같이 페이지 호출기에서 페이지 여백을 설정하십시오. 클립 패딩을 비활성화하는 것을 잊지 마십시오.

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

2
좋은 해결책이 제공되었습니다.
akash89

가장 쉽고 가장 좋은 방법
HannahCarney

이것은 짐승 네 짐승의 대답입니다. xd
silentsudo

1
참고 :이 기능은 맞춤보기 호출기 변환기와 함께 작동하지 않습니다.
voytez

@voytez 변압기 솔루션은 무엇입니까?
Alex

76
  1. 전체 항목보기에 대해 왼쪽 및 오른쪽 패딩을 설정하십시오. 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. 그런 다음 음수 페이지 여백 PageView을 2 * (이전보기 패딩)로 설정하십시오.

    int margin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20*2,     getResources().getDisplayMetrics());
    mViewPager.setPageMargin(-margin);
    
  3. 선택 과목. 빈 항목을 숨기려면 첫 번째 항목의 왼쪽 여백 없음과 오른쪽 항목의 마지막 여백을 설정하십시오. PageAdapter또는 Page클래스 에서이 작업을 수행 할 수 있습니다 .


@ Sergey, 솔루션 으로이 작업을 수행 할 수 없습니다. 예를 게시 할 수 있습니까? thx
Marckaraujo

12
메모를 추가하기 만하면 :이 솔루션을 사용하면 1 페이지에서 2 페이지로 슬라이드 할 때 3 페이지가 메모리에 없으므로 지연되어 나타납니다. 이 문제를 해결하려면 추가하십시오-yourViewPager.setOffscreenPageLimit (2);
José Barbosa

나는 똑같이하지만 마지막 항목에 대한 오버 스크롤 효과를 비활성화합니다. 그것에 대한 리드?
Swayam

스케일이 중앙 이미지로 설정된 이미지를 사용하면 여백이 무작위로 표시되는 것처럼 보입니다. 누구나 공유 할 수있는 작동 코드 예제가 있습니까?
kenyee

2
첫 번째 항목과 마지막 항목을 터치하는 방법은 무엇입니까? OnPageListener에서 페이지 색인을 확인하여?
Hardik9850

47

왼쪽 및 오른쪽 페이지의 미리보기를 표시하려면 다음 두 값을 설정하십시오.

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

viewpager에서 두 페이지 사이에 공백이 필요하면 viewpager.setPageMargin (int)를 추가하십시오.

Android ViewPager-왼쪽 및 오른쪽에 페이지 미리보기 표시


3
정답이어야합니다. 이전 버전의 viewpager에서는 작동하지 않았지만 지금은 작동합니다.
그렉 에니스

마지막 페이지의 첫 번째와 오른쪽에 동일한 여백을 추가합니다. 모든 수정
Umesh Aawte

1
짧고 명확한 답변.
Imran Ahmed

10

누군가 여전히 솔루션을 찾고 있다면 부정적인 마진을 사용하지 않고 ViewPage를 사용자 정의하여 샘플 프로젝트를 찾으십시오. https://github.com/44kksharma/Android-ViewPager-Carousel-UI 대부분의 경우 작동하지만 여전히 페이지 여백을 정의 할 수 있습니다 mPager.setPageMargin(margin in pixel);


1

여기에서 소스 코드를 다운로드하십시오 ( 이전 및 다음 페이지 경계가있는 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
이 코드는 제대로 작동하지 않습니다. 왼쪽보다 약간 왼쪽 페이지가 표시됩니다
Chirag Joshi

1

언젠가 나는 그러한 기능이 필요 했고 클래식 대신 PagerSnapHelper (v7 지원 라이브러리 버전 25.1.0에 추가) RecyclerView와 함께 사용하는 작은 라이브러리를 준비했습니다 .ViewPager

MetalRecyclerPagerView- 예제와 함께 모든 코드를 찾을 수 있습니다.

주로 단일 클래스 파일 MetalRecyclerViewPager.java (및 두 개의 XML : attrs.xmlids.xml )로 구성됩니다.

누군가에게 도움이되기를 바랍니다 :)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.