Android Viewpager - Show Preview of Page on Left and Right

ViewPager show next and before item preview on screen

Finally, i did it :) I modify this answer Android - Carousel like widget which displays a portion of the left and right elements

You can look this code.

//pager settings
pager.setClipToPadding(false);
pager.setPageMargin(24);
pager.setPadding(48, 8, 48, 8);
pager.setOffscreenPageLimit(3);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.i("", "onPageScrolled: " + position);

CampaignPagerFragment sampleFragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(position);

float scale = 1 - (positionOffset * RATIO_SCALE);

// Just a shortcut to findViewById(R.id.image).setScale(scale);
sampleFragment.scaleImage(scale);

if (position + 1 < pager.getAdapter().getCount()) {
sampleFragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(position + 1);
scale = positionOffset * RATIO_SCALE + (1 - RATIO_SCALE);
sampleFragment.scaleImage(scale);
}
}

@Override
public void onPageSelected(int position) {
Log.i("", "onPageSelected: " + position);
}

@Override
public void onPageScrollStateChanged(int state) {
Log.i("", "onPageScrollStateChanged: " + state);
if (state == ViewPager.SCROLL_STATE_IDLE) {
CampaignPagerFragment fragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(pager.getCurrentItem());
fragment.scaleImage(1);
if (pager.getCurrentItem() > 0) {
fragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(pager.getCurrentItem() - 1);
fragment.scaleImage(1 - RATIO_SCALE);
}

if (pager.getCurrentItem() + 1 < pager.getAdapter().getCount()) {
fragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(pager.getCurrentItem() + 1);
fragment.scaleImage(1 - RATIO_SCALE);
}
}

}
});

//PagerAdapter

public class CampaignPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

public CampaignPagerAdapter(FragmentManager fm) {
super(fm);
}

@Override
public int getCount() {
return 5;
}

@Override
public Fragment getItem(int position) {
return new CampaignPagerFragment();
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}

public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}

for ex: https://github.com/mrleolink/SimpleInfiniteCarousel..

Hello, One thing that is missing
sampleFragment.scaleImage(scale);
It is a method created in CampaignPagerFragment and it scale the fragment rootView..

e.g public void scaleImage(float scaleX)
{
rootView.setScaleY(scaleX);
rootView.invalidate();
}

Viewpager2 scrolling on preview left and right is not working

I honestly didn't find a true mean to make Viewpager2 works with swiping events on left and right preview since Viewpager2 class is final. But things worked out very well with using NestedScrollview.

UPDATED NEW SOLUTION
Thanks to CmTiger Who provided a more optimized way for scrolling. I have tested it. You can play with the value LEFT_RIGHT = 300 for left to right scrolling. get value from dp to pixel. however, you like it. This new solution need optimization.

    float last_x = 0;

nestedScrollView.setOnTouchListener(new View.OnTouchListener() {

int LEFT_RIGHT = -300; // your offsets
int RIGHT_LEFT = 300;

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float x = motionEvent.getX();

if (x > last_x) {
motionEvent.offsetLocation(LEFT_RIGHT, 0);
} else {
motionEvent.offsetLocation(RIGHT_LEFT, 0);
}

last_x = x;

viewpager.dispatchTouchEvent(motionEvent);
return false;
}
});

OLD SOLUTION

          <androidx.core.widget.NestedScrollView
android:id="@+id/nestedScroll"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="@dimen/_5sdp"
android:paddingStart="@dimen/_50sdp"
android:paddingEnd="@dimen/_50sdp"
/>
</androidx.core.widget.NestedScrollView>

Just use this code to make it work. Increase int value of speed to increase speed and vice versa.

  nestedScroll = view.findViewById(R.id.nestedScroll);

nestedScroll2.setOnTouchListener(new View.OnTouchListener() {
float start = 0;
float limit_to_start_moving = 5;
int speed = 7;
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {

if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
// Touch Starts X DOWN_X
start = motionEvent.getX();
}

if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
// get position
float X2 = motionEvent.getX();

if ((X2 - limit_to_start_moving) > start) {
// LEFT & RIGHT DIRECTION
if (start < X2)
viewpager.fakeDragBy((motionEvent.getXPrecision() * speed));
else
viewpager.fakeDragBy((motionEvent.getXPrecision() * -speed));
start = X2; // old position

} else if ((X2 + limit_to_start_moving) < start) {

if (start < X2)
viewpager.fakeDragBy((motionEvent.getXPrecision() * speed));
else
viewpager.fakeDragBy((motionEvent.getXPrecision() * -speed));
start = X2;

}
}

if (motionEvent.getAction() == MotionEvent.ACTION_UP) {

if (viewpager.isFakeDragging()) {
viewpager.endFakeDrag();
}

}

if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {

if (viewpager.isFakeDragging()) {
viewpager.endFakeDrag();
if (start > motionEvent.getX()) {
viewpager.setCurrentItem(viewpager.getCurrentItem() + 1);
} else {
viewpager.setCurrentItem(viewpager.getCurrentItem() - 1);
}
}

}

return false;
}
});

viewpager.setOnTouchListener(new View.OnTouchListener() {
float lastValue;
float value;
float delta;

@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
lastValue = event.getX();
viewpager.beginFakeDrag();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
value = event.getX();
delta = value - lastValue;
viewpager.fakeDragBy(delta * 2);
lastValue = value;
} else if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
viewpager.endFakeDrag();
}

return false;
}
});

How can i create ViewPager with previous and next page preview, and centred one zoomed from preview

viewPagerMusicCategory.setPageTransformer(false, new ViewPager.PageTransformer() {
@Override
public void transformPage(View page, float position) {
Log.e("pos",new Gson().toJson(position));
if (position < -1) {
page.setScaleY(0.7f);
page.setAlpha(1);
} else if (position <= 1) {
float scaleFactor = Math.max(0.7f, 1 - Math.abs(position - 0.14285715f));
page.setScaleX(scaleFactor);
Log.e("scale",new Gson().toJson(scaleFactor));
page.setScaleY(scaleFactor);
page.setAlpha(scaleFactor);
} else {
page.setScaleY(0.7f);
page.setAlpha(1);
}
}
}
);

....

ViewPager with previous and next page boundaries

Quoting myself from a blog post on this subject:

The third approach comes from Dave Smith, co-author of the well-regarded book Android Recipes. He went in a very different direction, using a custom container that disabled children clipping to show more than one page at a time.

His published sample code shows the whole thing in action. His container (com.example.pagercontainer.PagerContainer) wraps the ViewPager and calls setClipChildren(false); on itself, so even though the ViewPager is focused on one selected page, other pages that have coordinates beyond the ViewPager bounds are still visible, so long as they fit within the PagerContainer. By sizing the ViewPager to be smaller than the PagerContainer, the ViewPager can size its pages to that size, leaving room for other pages to be seen. PagerContainer, though, needs to help out a bit with touch events, as ViewPager will only handle swipe events on its own visible bounds, ignoring any pages visible to the sides.

Sample Image

Android ViewPager with previous and next pages visible?

I used a negative page margin to partly show the next and the previous pages. The fading edge property can be used to make previous/next page fade:

ViewPager examplePager = (ViewPager) findViewById(R.id.exampleView);
examplePager.setPageMargin(-50);
examplePager.setHorizontalFadingEdgeEnabled(true);
examplePager.setFadingEdgeLength(30);

The lastest support package (revision 4, October 2011) is also required for this to work



Related Topics



Leave a reply



Submit