Sliding view used to control ViewPager paging - android

My goal is to have a sliding view on fragment 1 which slides a set distance before fragment 2 is pulled into visual view.
I made a visual here that shows what I am trying to do:
Pic 1 Shows the default view of fragment 1 (pink) and sliding view (green), nothing has happened in this state.
Pic 2 The sliding view is able to slide to it's cutoff (black line). It cannot move past this on this fragment.
Pic 3 The entire fragment 1 begins to slide, fragment 2 (blue) is now starting to be pulled into the view
Pic 4 Both fragments continue to slide as before.
Pic 5 Fragment 2 has now slid into view.
When the user tries to return to the previous screen the transition happens in reverse.
Right now I have implemented a ViewPager which hosts the fragments 1 and 2. The default ViewPager behavior allows me to slide between the two fragments, but I am unsure how to implement the functionality I have described.

I was able to achieve the desired transition with the use of a ViewPager PageTransformer
I am using Xamarin.Android in my project, so C# is used. Although this snippet is in C# it could easily be ported to Java code for use in other projects.
float passpoint = 7/8f;
public void TransformPage(View view, float position)
{
var pageWidth = view.Width;
var slidingGap = pageWidth - pageWidth * passpoint;
var translation = position * pageWidth;
if (position < -1)
{ // [-Infinity,-1)
// This page is way off-screen to the left.
view.Alpha = 0;
}
else if (position <= 1)
{ // [-1,1]
var r = new Rect();
//if valid, this view is the startpage
Button button = (Button)view.FindViewById(Resource.Id.slidingButton);
if (button != null)
{
var posPassPoint = -(1 - passpoint);
float ratio;
//create sliding gap
if (position > posPassPoint)
{
ratio = RatioBetween(position, posPassPoint, 0);
button.TranslationX = slidingGap * -ratio;
}
//compensate for sliding gap after it has been reached
else
{
//1- bc want the ratio to shrink
ratio = 1-RatioBetween(position, -1, posPassPoint);
}
view.TranslationX = slidingGap * ratio;
}
//valid on views other than start page (no sliding button)
if (button == null)
{
float ratio;
//create sliding gap
if (position >= passpoint)
ratio = RatioBetween(position, passpoint, 1);
//compensate for sliding gap after it has been reached
else
ratio = 1 - RatioBetween(position, 0, passpoint);
view.TranslationX = slidingGap * ratio;
}
}
else
{ // (1,+Infinity]
// This page is way off-screen to the right.
view.Alpha = 0;
}
}
float RatioBetween(float input, float upperBound, float lowerBound)
{
return (input - lowerBound) / (upperBound - lowerBound);
}

Related

ViewPager2 - Slider transition sliding too fast

I have implemented from the documentation of viewpager2 the follow animation
private const val MIN_SCALE = 0.85f
private const val MIN_ALPHA = 0.5f
class ZoomOutPageTransformer : ViewPager2.PageTransformer {
override fun transformPage(view: View, position: Float) {
view.apply {
val pageWidth = width
val pageHeight = height
when {
position < -1 -> { // [-Infinity,-1)
// This page is way off-screen to the left.
alpha = 0f
}
position <= 1 -> { // [-1,1]
// Modify the default slide transition to shrink the page as well
val scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position))
val vertMargin = pageHeight * (1 - scaleFactor) / 2
val horzMargin = pageWidth * (1 - scaleFactor) / 2
translationX = if (position < 0) {
horzMargin - vertMargin / 2
} else {
horzMargin + vertMargin / 2
}
// Scale the page down (between MIN_SCALE and 1)
scaleX = scaleFactor
scaleY = scaleFactor
// Fade the page relative to its size.
alpha = (MIN_ALPHA +
(((scaleFactor - MIN_SCALE) / (1 - MIN_SCALE)) * (1 - MIN_ALPHA)))
}
else -> { // (1,+Infinity]
// This page is way off-screen to the right.
alpha = 0f
}
}
}
}
}
Now, in my activity I wraped this animation with a Handler to automatically swipe, but is going really fast that I cant even notice when its sliding
private fun slideViewPager(){
var currentPage = 0
var timer: Timer? = null
val DELAY_MS: Long = 2000 //delay in milliseconds before task is to be executed
val PERIOD_MS: Long = 3000
val handler = Handler()
val update = Runnable {
if (currentPage == NUM_PAGES - 1) {
currentPage = 0
}
viewPager.setCurrentItem(currentPage++, true)
}
timer = Timer() // This will create a new Thread
timer!!.schedule(object : TimerTask() { // task to be scheduled
override fun run() {
handler.post(update)
}
}, DELAY_MS, PERIOD_MS)
}
I have adjusted the delay from the handler, but is not that the problem, because that just delays when its gonna change to the other page, but the transition during this change is really fast, how can I slow it down ?
I have encountered a similar problem when working with ViewPager2. I had two items in my ViewPager, and put the switch to the next item as the action of a button. The first time you press it, the animation is instantaneous, like you describe. However, in my setup, if you press again on it, it scrolls back to the left. Once it does that, the animation works correctly (both left and right).
From what I can tell from your code, in your case you continue to scroll in a single direction - hence you only observe the instantaneous scrolling. Try to play around with it and make it scroll back, instead of only forward. See if the animation appears correctly in that case.
EDIT: If you find that the same behavior applies in your case as well, you can apply a completely inelegant hack:
You can "browse" through your ViewPager's items when you're opening up your activity, as quickly as possible. Then, after going through each item, switch back to the first item and then just apply whatever logic you have now. If you do this, the items will already be "loaded" and the animations will work.
Of course, while you're doing that in the "background", you can display a progress loader when you first get into the activity, and once you've scrolled back to the first item, display your activity. The user will think the activity is "loading", but in reality you will be going through each of your ViewPager's items, effectively "pre-loading" them.
Completely ugly solution, but it should work. I hope someone can come up with a better one than this, as I don't exactly know the reason why the animation isn't playing correctly the first time.

View pager 2: Depth Page Transformation make fragment click events disable on pager swipe up

I am using viewpager2 with fragmentStateAdapter.
Also, setting page transformer as DepthPageTransformation(transition is working correctly the way I want)
But when I swipe up the pages, the on click events on that fragment works on double click(event works after clicking twice on it)
If I remove pageTransformation from the viewPager, then it works fine.
So, not able to understand that why is transformation causing click event problem.
private static final float MIN_SCALE = 0.75f;
public void transformPage(#NonNull View view, float position) {
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
Log.d("batman",position+" <-1");
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1f);
view.setTranslationY(0f);
view.setScaleX(1f);
view.setScaleY(1f);
Log.d("batman",position+" <=0");
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationY(pageHeight * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
Log.d("batman",position+" <=1");
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
Log.d("batman",position+" else");
}
}
}
HomeFragment(adapter setting):
mAdapter = new ViewPagerAdapter(this);
setPageChangeListener();
mViewPager.setAdapter(mAdapter);
// mViewPager.setOffscreenPageLimit(3);
mViewPager.setPageTransformer( new DepthPageTransformer());
I want that button click event should work at one click when the page is swiped up.
The clicks of the previous fragment were getting disabled on swipe up because I was updating my fragment which is added in view pager from onPageSelected() listener, so that was making the button work on double click.
#Override
public void onPageSelected(int position) {
homePresenter.onPageSelected();
currentPg = position;
}
Maybe we cannot update our fragment from this listener.

ViewPager with left and right preview

I need to set up a ViewPager with the following requirements:
- at any given time, 3 pages must be visible in the screen
- the center page isn't scaled and the behind pages are 60% of the center page;
- center page, must overlap a bit the behind pages.
From what I saw in other questions I've tried to do this:
viewPager.setClipToPadding(false);
int padding = (metrics.widthPixels - centerViewSize) / 2;
viewPager.setPadding(padding, 0, padding, 0);
viewPager.setPageMargin(-(padding / 2));
viewPager.setCurrentItem(10);
viewPager.setOffscreenPageLimit(3);
Doing this got me here:
This is what I was expecting. Just need to bring to front the current selected item.
I've then tried to scale the view with:
public static final float SCALED_SIZE = 0.6f;
viewPager.setPageTransformer(false, new PageTransformer() {
#Override
public void transformPage(final View page, final float position) {
if (position < -1) {
page.setScaleX(SCALED_SIZE);
page.setScaleY(SCALED_SIZE);
} else if (position <= 1) {
float scaleFactor = Math.max(SCALED_SIZE, 1 - Math.abs(position));
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
} else {
page.setScaleX(SCALED_SIZE);
page.setScaleY(SCALED_SIZE);
}
}});
But that gives me some problems.
The first item that should be selected is not the correct one.
Animation chopy.
At some points, there are more than 3 pages on the screen.
Scale is from the bottom and I would like to be from the center.
Any idea how I can solve my issues?
use Library UltraViewPager. It have very nice effects.

ViewPager animation like Gallery app

I'm trying to change my ViewPager transition animation.
I'd like to have the same behavior as the default gallery, when you switch from one photo to the next one. It's basically an animation where the current page goes to the left while the next one comes from behind it and grows larger.
I've seen that I can change the animation with a PageTransformer.
pager.setPageTransformer(false, new PageTransformer() {
#Override
public void transformPage(View page, float position) {
if (position < 0) {
} else {
final float normalizedposition = Math.abs(Math.abs(position) - 1);
page.setScaleX(normalizedposition / 2 + 0.5f);
page.setScaleY(normalizedposition / 2 + 0.5f);
}
}
});
With that, I have the current page sliding to the left, that's ok.
The new page starts small in size and grows, that's also ok. But, the page comes from the right to center. I'd like to remove the translation and have it already in the middle, but small, hidden by the current page.
If I add page.setTranslationX(1080 * (-(position))); then the next pages stays in the middle of the screen, but they are visible at all time above the current page. If I also add alpha to the page, the page appearing isn't hidden behind the old one.
I've tried to check in the source code of the gallery app but I didn't found any reference to the transformPage function.
Turns out to be easy. It is in the demos in the android developper website.
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
See here (Depth page transformer).

Animation proxy from nineoldandroid was not working 2.2

friends....
I got a problem with animation in betwen versions...So i will give description about the requirements of my app and problem im facing
1.My consists of animation which consists viewpager.
2.And this animation must work in lower versions such as 2.2.
3.So for this i have found a awsome library ninoldandroid.
4.I have used animation proxy for my animation.
5.It waa working fine in 4.2.
6.But when coming to 2.2 the animation was not working and the viewpager was moving with its default feature.
My code for animation is...
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
AnimatorProxy proxy = AnimatorProxy.wrap(view);
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
proxy.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
proxy.setAlpha(1);
proxy.setTranslationX(0);
proxy.setScaleX(1);
proxy.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
proxy.setAlpha(1 - position);
// Counteract the default slide transition
proxy.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
proxy.setScaleX(scaleFactor);
proxy.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
proxy.setAlpha(0);
}
}
}
Can u tell what i have to implement to make this anim ation work in 2.2.
If u feel that the question is insuffient please let me know..Thnaq
There is a Animated view pager by jfeinstein JazzyViewPager which is used by nineoldandroid. which work from 2.2.
(Sorry for late replay)

Categories

Resources