Is there a way to create a preview slider in android

I'm trying to create an interface like

here .

The central ViewPager element with a full-size image, the top element is a RecyclerView with preview images. But I could not find a way to center the magnetic elements. Is there a way to override the behavior of a RecyclerView ?

+4
android android-viewpager android-view android-recyclerview
source share
3 answers

I found a solution exactly what you need. I created a small example on github.com: AndroidPreviewSlider

Preview

The fact is that the top view is a ViewPager , and in the center is a ViewPager . Detailed code below:

Preview adapter

 public class PhotoPreviewAdapter extends FragmentPagerAdapter { private static final int DEFAULT_SIDE_PREVIEW_COUNT = 3; private final int sidePreviewCount; private final List<PhotoInfo> photoInfos; public PhotoPreviewAdapter(FragmentManager fm, List<PhotoInfo> photoInfos) { this(fm, DEFAULT_SIDE_PREVIEW_COUNT, photoInfos); } public PhotoPreviewAdapter(FragmentManager fm, int sidePreviewCount, List<PhotoInfo> photoInfos) { super(fm); this.sidePreviewCount = sidePreviewCount; this.photoInfos = photoInfos; } public int getSidePreviewCount() { return sidePreviewCount; } @Override public Fragment getItem(int position) { if (isDummy(position)) { return DummyPreviewFragment.newInstance(); } else { return PhotoPreviewFragment.newInstance(photoInfos.get(getRealPosition(position))); } } private boolean isDummy(int position) { return position < sidePreviewCount || position > photoInfos.size() - 1 + sidePreviewCount; } private int getRealPosition(int position) { return position - sidePreviewCount; } @Override public int getCount() { return photoInfos.size() + (sidePreviewCount * 2); } @Override public float getPageWidth(int position) { return 1.0f / getElementsPerPage(); } private int getElementsPerPage() { return (sidePreviewCount * 2) + 1; } } 

Central viewing adapter is simple

 public class PhotoViewAdapter extends FragmentPagerAdapter { private final List<PhotoInfo> photoInfos; public PhotoViewAdapter(FragmentManager fm, List<PhotoInfo> photoInfos) { super(fm); this.photoInfos = photoInfos; } @Override public Fragment getItem(int position) { return PhotoViewFragment.newInstance(photoInfos.get(position)); } @Override public int getCount() { return photoInfos.size(); } } 

And one of the main synchronization listener

 public class OnSyncPageChangeListener implements ViewPager.OnPageChangeListener { private int scrollState = ViewPager.SCROLL_STATE_IDLE; private final ViewPager syncToViewPager; private final ViewPager syncWithViewPager; public OnSyncPageChangeListener(ViewPager syncToViewPager, ViewPager syncWithViewPager) { this.syncToViewPager = syncToViewPager; this.syncWithViewPager = syncWithViewPager; } @Override public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) { if (scrollState != ViewPager.SCROLL_STATE_IDLE) { final float ratio = calculateRatioForPosition(position); final float scrollX = syncWithViewPager.getScrollX(); final float scrollY = syncWithViewPager.getScrollY(); syncToViewPager.scrollTo((int) (scrollX * ratio), (int) scrollY); } } private float calculateRatioForPosition(int position) { final float syncToViewPagerWidth = syncToViewPager.getWidth(); final float syncWithViewPagerWidth = syncWithViewPager.getWidth(); final float syncToViewPagerElementWeight = syncToViewPager.getAdapter().getPageWidth(position); final float syncWithViewPagerElementWeight = syncWithViewPager.getAdapter().getPageWidth(position); final float syncToViewPagerElementsCount = (1.0f / syncToViewPagerElementWeight); final float syncWithViewPagerElementsCount = (1.0f / syncWithViewPagerElementWeight); final float syncToViewPagerElementWidth = syncToViewPagerWidth / syncToViewPagerElementsCount; final float syncWithViewPagerElementWidth = syncWithViewPagerWidth / syncWithViewPagerElementsCount; return syncToViewPagerElementWidth / syncWithViewPagerElementWidth; } @Override public void onPageSelected(final int position) { } @Override public void onPageScrollStateChanged(final int state) { scrollState = state; if (state == ViewPager.SCROLL_STATE_IDLE) { syncToViewPager.setCurrentItem(syncWithViewPager.getCurrentItem(), false); } } } 

And finally init ViewPager

 @Bind(R.id.photoPreviewPager) ViewPager photoPreviewPager; @Bind(R.id.photoViewPager) ViewPager photoViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); final List<PhotoInfo> photoInfos = PhotoInfosProvider.generate(); final PhotoPreviewAdapter photoPreviewAdapter = new PhotoPreviewAdapter(getSupportFragmentManager(), photoInfos); final PhotoViewAdapter photoViewAdapter = new PhotoViewAdapter(getSupportFragmentManager(), photoInfos); photoPreviewPager.setAdapter(photoPreviewAdapter); photoPreviewPager.addOnPageChangeListener(new OnSyncPageChangeListener(photoViewPager, photoPreviewPager)); photoViewPager.setAdapter(photoViewAdapter); photoViewPager.setOffscreenPageLimit(photoPreviewAdapter.getSidePreviewCount() * 2 + 1); photoViewPager.addOnPageChangeListener(new OnSyncPageChangeListener(photoPreviewPager, photoViewPager)); } 

More detailed code is in repo

+4
source share

LinearLayoutManager has a scrollToPositionWithOffset method that takes both the position and the offset of the beginning of the element from the beginning of the RecyclerView, which seems to do what you need.
You can use this image slider ( https://github.com/jjhesk/LoyalNativeSlider ) instead of ViewPager.

+1
source share

First of all, you can use this official Google example to create a visual effect of distracting this view to the center. You will have an ImageView over the ViewPager to display animated images. When the animation is complete, make your ImageView Gone and show the requested image in the ViewPager.

0
source share

All Articles