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


107

Android의 ViewPager. 내가 원하는 것은 왼쪽과 오른쪽에 페이지의 미리보기를 표시하는 것입니다. 네거티브 pageMargin를 사용 하여 오른쪽 미리보기를 표시 할 수있는 위치를 확인 했습니다.

setPageMargin(-100);

어쨌든 왼쪽도 미리 볼 수 있나요? 기본적으로 내가 찾고있는 갤러리 위젯과 비슷한 것입니다.


좋은 질문! 최근에 소스를 확인했는데 src 코드를 수정하고 싶지 않다면 더 좋은 방법이 없다고 생각합니다. setPageMargin(-100)제대로 작동 합니까 ?
Macarse

조각과 함께 ViewPger를 사용하지 않는 한 GalleryView는 작업을 더 잘 수행합니다.
Ali AlNoaimi

갤러리보기를 사용하여이 작업을 수행 할 수있었습니다. 어떤 식 으로든 뷰 페이저와 동일합니다. 갤러리가 더 이상 사용되지 않는 이유를
모름

이 질문은 이후 광범위하게 [여기 포스트]에 덮여있다 [1] [1] : stackoverflow.com/questions/13914609/...
벤 피어슨

Vierpager를 조각과 함께 사용하고 있는데 동일한 접근 방식을 사용할 수 있습니까?
asliyanage

답변:


206

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

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

뷰 페이저에서 두 페이지 사이에 공간이 필요하면 다음을 추가하십시오.

viewpager.setPageMargin(int);

2
예, Jiju Induchoodan에 동의합니다 .. 자세한 내용은 blog.neteril.org/blog/2013/10/14/…stackoverflow.com/questions/13914609/…
Sripathi

멋지다, 너무 간단하다 :) 뷰 페이저의 전환 페이지에서 오른쪽 및 왼쪽 크기의 미리보기 크기를 조정할 수 있습니까? 예를 들어-초점이 맞지 않는 조각의 경우 배율은 ~ 0.8이되지만 중앙으로 끌면 배율이 1로 증가하고 화면 밖으로 나갈 때 중앙보기의 이전 조각이 배율이 0.8로 변경됩니까?
iamthevoid 2010 년

작동 중입니다! 그러나 중앙 레이아웃을 확대하려고하면 위쪽과 아래쪽으로 확대됩니다. 패딩으로 인해 왼쪽과 오른쪽이 보이지 않습니다. stackoverflow.com/questions/52710076/…
Anooj Krishnan G

viewpager 2에서 작동하지 않음
hamiid reza Gholami

73

@JijuInduchoodan의 대답은 완벽하고 효과적입니다. 그러나 저는 안드로이드에 비교적 익숙하지 않기 때문에 제대로 이해하고 설정하는 데 시간이 걸렸습니다. 그래서 나는 미래의 참조를 위해이 답변을 게시하고 나와 같은 입장에있는 다른 사람을 돕습니다.

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's어댑터 의 페이지에 너비를 설정할 필요가 없습니다 . 에서 이전 및 다음 페이지를 보는 데 필요한 추가 코드가 없습니다 ViewPager. 단, 각 페이지의 상단과 하단에 빈 공간을 추가하려면 다음 코드를 ViewPager's하위 페이지의 상위 레이아웃으로 설정할 수 있습니다 .

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

최종 ViewPager

이것이 ViewPager의 최종 모습입니다.


62

새로운 ViewPager2 솔루션

요즘에는 " ViewPager대체하여 이전 버전의 문제점 대부분을 해결"하는 ViewPager2 사용을 고려해야 합니다 .

  • RecyclerView 기반
  • RTL (오른쪽에서 왼쪽으로) 레이아웃 지원
  • 수직 방향 지원
  • 신뢰할 수있는 Fragment 지원 (기본 Fragment 컬렉션에 대한 변경 처리 포함)
  • 데이터 세트 변경 애니메이션 ( DiffUtil지원 포함 )

결과

여기에 이미지 설명 입력

코드

활동 / 조각에서 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)

추가 HorizontalMarginItemDecoration사소한 인 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
    }

}

이전 / 다음 항목이 표시되는 정도와 현재 항목 가로 여백을 제어하는 ​​차원을 추가합니다.

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

여기에 이미지 설명 입력

마지막으로 ViewPager2레이아웃 에을 추가하십시오 .

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

한 가지 중요한 것은 ViewPager2항목에 있어야합니다 layout_height="match_parent"(그렇지 않으면 IllegalStateException이 발생 함). 따라서 다음과 같이해야합니다.

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

Google은 PageTransformer영감으로 사용할 수있는 두 가지 구현이있는 ViewPager2에 대한 가이드를 추가했습니다 . https://developer.android.com/training/animation/screen-slide-2

새로운 ViewPager2 정보


oreo 장치에서 동일한 문제, 패딩 시작 및 끝이 다른 장치에서 예상대로 작동하지만 ViewPager2 이후에는 oreo가 작동합니다. PageTransformer가 문제를 해결했으며 패딩은 여전히 ​​동일하며 추가해야했습니다viewpager.setPageTransformer { page, position -> page.translationX = -1 * position }
zgr

이 효과를 얻으려면 뷰 페이저의 페이지를 약간 이동해야합니다
Muhammad Saqib

신경 쓰지 마세요.이 줄을 추가하는 것을 잊었습니다. setOffscreenPageLimit(1):)
Muhammad Saqib

이것은 내가 찾은 최고의 솔루션입니다. 완벽하게 작동하지만 예 ViewPager2의 항목 너비, 높이를 MATCH_PARENT로 설정하는 것을 잊지 마십시오.
khushbu

26

2017 년 RecyclerView에는 PagerSnapHelper (v7 지원 라이브러리의 버전 25.1.0에 추가됨)를 사용하여 이러한 동작을 추가로 쉽게 수행 할 수 있습니다 . 

여기에 이미지 설명 입력

언젠가 나는 그러한 뷰 페이저와 같은 기능이 필요했고 작은 라이브러리를 준비했습니다.

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

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

누군가를 돕고 몇 시간을 절약하기를 바랍니다. :)


가끔 호출기 만 필요하기 때문에 주제에서 벗어 났지만 알아두면 좋습니다! 공유해 주셔서 감사합니다!
sud007 2017

굉장합니다. 이미 많은 RecyclerView 도우미 코드가 있습니다. 간단하게 추가하면 new PagerSnapHelper().attachToRecyclerView(recyclerView)페이지 스냅이 있습니다.
Steve

9

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


7

xml 파일에서이 작업을 수행 할 수 있습니다. 아래 코드를 사용하면됩니다.

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

예를 들면 :

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

참고 : 페이지 사이에 공백이 필요한 경우 패딩 / 여백을 하위 조각으로 설정하십시오.


3
나는 반대표를 던졌다. 죄송합니다. 이번에는 효과가 있었다 !! 다시 Upvoted
shikhar 반살

1

다른 화면에서이 기능을 사용하는 데 어려움을 겪는 분들을 위해

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

이 조각 어댑터 및 클래스를 사용하여 왼쪽 및 오른쪽 스크롤에서 뷰 페이지를보고 다음 페이지를보기 위해 스크롤하는 데 필요한 클래스를 추가합니다.

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

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