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 theViewPager
and callssetClipChildren(false);
on itself, so even though theViewPager
is focused on one selected page, other pages that have coordinates beyond theViewPager
bounds are still visible, so long as they fit within thePagerContainer
. By sizing theViewPager
to be smaller than thePagerContainer
, theViewPager
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, asViewPager
will only handle swipe events on its own visible bounds, ignoring any pages visible to the sides.
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
Best Way to Show a Loading/Progress Indicator
Use Dll Files in Android Application
Fragment's Onsaveinstancestate() Is Never Called
Gradle Dsl Method Not Found: 'Implementation()'
How to Get Android Avd Name from Adb Device Name
What Is Metadata ? and What Is The Use of It in Android
Particular Title(Fetched from API) Using Searchview
Eclipse Can't Find Android.Support.V4.Widget.Swiperefreshlayout
How to Add Padding Between Menu Items in Android
How to Know Whether a Recyclerview/Linearlayoutmanager Is Scrolled to Top or Bottom
Android/View/View$Onunhandledkeyeventlistener (Onmeasure Error)
Supportmapfragment Does Not Support Androidx Fragment
How to Add Network_Security_Config.Xml to Manifest in Expo App Without Ejecting
Call Recorder Not Working in Android 10 (Q)
How to Integrate Samsung Gear Steps in Android Application