OnPageChangeListener alpha crossfading - android

There are a lot of questions with regard to crossfading in Android, but they all include animations. My question is about crossfading using the OnPageChangeListener of a ViewPager.
I have a ViewPager which could have an unlimited number of views, but in practice uses about 6 or 7 views. Not much going on there.
Each View in the ViewPager has a background Bitmap which should be fixed and crossfade with the background of the next (or previous) View instead of scrolling along with the rest of the View.
To achieve this I decoupled the backgrounds and add to an ArrayList and assign them to ImageViews later. But since I don't want to risk the chance that my Activity will end up with numerous ImageViews I thought of the following structure:
<FrameLayout
android:id="#+id/backgroundContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/bottomImage"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="center" />
<ImageView
android:id="#+id/middleImage"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="center" />
<ImageView
android:id="#+id/topImage"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="center" />
</FrameLayout>
Then a OnPageChangeListener is assigned to the ViewPager to assign the backgrounds to the ImageViews.
#Override
public void onPageSelected(int position) {
MyLog.i(TAG, "PAGE SELECTED: " + position);
if(position == 0) {
_bottomBackground.setImageBitmap(null);
_topBackground.setImageBitmap(_backgroundStack.get(position+1));
} else if (position == NUM_ITEMS-1) {
_bottomBackground.setImageBitmap(_backgroundStack.get(position-1));
_topBackground.setImageBitmap(null);
} else {
_bottomBackground.setImageBitmap(_backgroundStack.get(position-1));
_topBackground.setImageBitmap(_backgroundStack.get(position+1));
}
_middleBackground.setImageBitmap(_backgroundStack.get(position));
// Make the top front background transparent
_topBackground.setAlpha(0f);
_currentBackgroundPosition = position;
}
This works fine if I would've liked to just swap the backgrounds. I want the backgrounds to cross fade into each other while the user swipes the ViewPager. I've got the fade for a forward scroll working, but I don't understand why the fade for the backward scroll somehow doesn't give a good result. During a backward scroll the middle background should fade into the bottom background.
I'm afraid I'm missing something. I'm never changing the alpha of the bottom background, but the Log results always show the exact same value for getAlpha() as for the middle background.
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(_currentBackgroundPosition == position) {
// scroll forward
_topBackground.setAlpha(positionOffset)
} else {
//scroll backward
_middleBackground.setAlpha(positionOffset);
}
MyLog.i(TAG, "Bottom BackgroundAlpha: " + _bottomBackground.getAlpha());
MyLog.i(TAG, "Middle BackgroundAlpha: " + _middleBackground.getAlpha());
MyLog.i(TAG, "Top BackgroundAlpha: " + _topBackground.getAlpha());
}
And wait! There's one more thing I really am not able to figure out how to fix. Although the forward scroll fade is working. There's a super short flickering in the background. I assume this is happening because of way I set up the onPageSelected method.
Is there another way how I can create/fix this behavior?

ViewPager.PageTransformer is your friend. I'm going to take a different approach to what you tried, but it results in what I understand to bed your desired result - swiping left/right swipes the content, but fades between two background images that don't move.
Each Fragment in the ViewPager will have a layout like so:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/image_view"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scaleType="center" />
<LinearLayout
android:id="#+id/content_area"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- content goes here -->
</LinearLayout>
</FrameLayout>
And you will create a PageTransformer that manipulates the layout depending the position it has been swiped:
public class CustomPageTransformer implements ViewPager.PageTransformer {
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
View imageView = view.findViewById(R.id.image_view);
View contentView = view.findViewById(R.id.content_area);
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left
} else if (position <= 0) { // [-1,0]
// This page is moving out to the left
// Counteract the default swipe
view.setTranslationX(pageWidth * -position);
if (contentView != null) {
// But swipe the contentView
contentView.setTranslationX(pageWidth * position);
}
if (imageView != null) {
// Fade the image in
imageView.setAlpha(1 + position);
}
} else if (position <= 1) { // (0,1]
// This page is moving in from the right
// Counteract the default swipe
view.setTranslationX(pageWidth * -position);
if (contentView != null) {
// But swipe the contentView
contentView.setTranslationX(pageWidth * position);
}
if (imageView != null) {
// Fade the image out
imageView.setAlpha(1 - position);
}
} else { // (1,+Infinity]
// This page is way off-screen to the right
}
}
}
And finally hook this PageTransformer up to your ViewPager:
mViewPager.setPageTransformer(true, new CustomPageTransformer());
I've tested it in an existing app and it works well as long as the fragment layouts have a transparent background.

Related

How to fix unexpected behavior on viewpager in recyclerview when fast scrolling?

My RecyclerView has viewpager on each row for several swipeable buttons.
When I scroll fast in a default state, it works fine.
But some views (pages) are partially shown on default pages. I can watch them they are swiped to default page from swiped page before (Actually not theirs. Single row which is recycled in above)
Sometimes really small 'partial view' is appeared corner even if they were set as default like below.
Left top corner. I didn't even touch that row at all.
I suspect it's inflating speed, so I used SparseIntArray, Remove another view, Make small array for the test, Remove resources on views. But all were worthless.
Also results in SparseIntArray are all normal as expected.
Here are some codes below. Also, all xmls are
PageWidth
public float getPageWidth(int position)
{
if(position != 3 && position != 0)
{
return 0.15f;
}
else
{
return 1f;
}
}
Init and Load
#Override
public void onBindViewHolder(#NonNull mAdapter.ClipViewHolder clipViewHolder, int position)
{
if(stateArray.get(position) > 0 && stateArray.get(position) <= 4)
{
clipViewHolder.myPager.setCurrentItem(stateArray.get(position) - 1);
}
else
{
clipViewHolder.myPager.setCurrentItem(3);
stateArray.append(position, clipViewHolder.myPager.getCurrentItem() + 1);
}
}
Save
#Override
public void onViewRecycled(#NonNull ClipViewHolder holder)
{
stateArray.put(holder.getAdapterPosition(), holder.myPager.getCurrentItem() + 1);
super.onViewRecycled(holder);
}
I want to show them smoothly no matter what swipe state was, no matter how fast scroll speed. Is there any solution?
//Put below code in XML file
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycleView"
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
/>
// put below lines in your activity as
/* catche memory */
recyclerView.setItemViewCacheSize(200);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
RecyclerView.LayoutManager mLayoutManager = new
LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
//for smooth recycler
recyclerView.setNestedScrollingEnabled(false); // Main Line
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.smoothScrollBy(0, 10);

How to make bottom sheet (BottomSheetBehavior) expandable to arbitrary position?

I have bottom sheet, and I want to change its behavior so it would work like on the main screen of Google Maps application, where you can expand it to any position and leave it there and it won't automatically stick to the bottom or to the top. Here's my layout with bottom sheet:
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<View
android:id="#+id/shadow"
android:layout_width="match_parent"
android:layout_height="16dp"
android:background="#drawable/shape_gradient_top_shadow"
app:layout_anchor="#+id/map_bottom_sheet" />
<LinearLayout
android:id="#+id/map_bottom_sheet"
android:layout_width="match_parent"
android:layout_height="300dp"
android:fillViewport="false"
android:orientation="vertical"
app:behavior_peekHeight="50dp"
android:background="#color/lightGray"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<include layout="#layout/bottom_sheet_top_buttons"/>
<android.support.v4.widget.NestedScrollView
android:id="#+id/bottom_sheet_content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/lightGray"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
What I need in essence is eliminate forcing of STATE_EXPANDED and STATE_COLLAPSED states when dragging is ended.
Here's a visual explanation of what I try to achieve:
As you can see, bottom sheet doesn't automatically anchor to the top or the bottom but stays at whatever position it was left.
Copy the code from android.support.design.widget.BottomSheetBehavior to make your own custom behavior. Then modify the onViewReleased() method which is responsible for the movement of the sheet after the drag ends. You also have to introduce a new state besides the existing ones - the state is helpful to restore the position and let others know in which state your sheet is at the moment with getState().
#Override
public void onViewReleased(View releasedChild, float xVel, float yVel) {
int top;
#State int targetState;
// Use the position where the drag ended as new top
top = releasedChild.getTop();
// You have to manage the states here, too (introduce a new one)
targetState = STATE_ANCHORED;
if (mViewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), top)) {
setStateInternal(STATE_SETTLING);
ViewCompat.postOnAnimation(releasedChild, new SettleRunnable(releasedChild, targetState));
} else {
setStateInternal(targetState);
}
}
I have created a proof of concept originating from the orginal source code from the design library. You can view it here. The problem with the original behavior is it doesn't allow flings, and most methods are private so extending the class and overriding some methods in an attempt to achieve it won't get you very far either. My implementation allows for optional snapping behavior, transient states (don't automatically snap after drag) and customizations around setting peek height and max height.
Hi Alex you can try this code for similar expected behaviour, it is not as optimised but it will help you to understand the concept.
final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
bottomSheetBehavior.setPeekHeight(200);
// set callback for changes
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
Log.d(TAG, "onStateChanged: " + bottomSheet.getY() + "::" + bottomSheet.getMeasuredHeight() + " :: " + bottomSheet.getTop());
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
ViewGroup.LayoutParams params = bottomSheet.getLayoutParams();
params.height = Math.max(0, metrics.heightPixels - (int) bottomSheet.getTop());
bottomSheet.setLayoutParams(params);
}
});

Animate view from outside of bounds to show partly then full

I am currently struggling to find a good way how to animate some views in a specific way.
Following screenshots should show what I want to achieve:
First state (HIDDEN):
Second state (COLLAPSED)
Third state (EXPANDED)
The change between these states should be animated.
Those views are not draggable or slideable at all.
I know that there is the SlidingUpPanel by umano but I think that would be kind of an overkill.
At the moment the way I achieve this behaviour is the following:
I wrap the 2 panels (top and bot) in a relative layout and use the property animator to animate a change of the height of the relative layout.
So when the state is COLLAPSED then the height of the relative layout will be animated from 0 to the height of the top panel.
This works fine but I think that this is a really bad way to do this.
I already tried out to create a custom ViewGroup but the animating part didnt work yet.
Any input is appreciated.
I would use FrameLayout here as follows:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/screen"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
android:id="#+id/top_panel"
android:layout_width="match_parent"
android:layout_height="#dimen/top_panel_height"
android:layout_gravity="bottom"/>
<FrameLayout
android:id="#+id/bottom_panel"
android:layout_width="match_parent"
android:layout_height="#dimen/bottom_panel_height"
android:layout_gravity="bottom"/>
</FrameLayout>
Then, create enum for states
enum State {
HIDDEN {
#Override
public void moveTo(View topPanel, View bottomPanel, long animationDuration) {
topPanel.animate().translationY(topPanel.getHeight()).setDuration(animationDuration);
bottomPanel.animate().translationY(topPanel.getHeight() + bottomPanel.getHeight()).setDuration(animationDuration);
}
},
COLLAPSED {
#Override
public void moveTo(View topPanel, View bottomPanel, long animationDuration) {
topPanel.animate().translationY(0).setDuration(animationDuration);
bottomPanel.animate().translationY(bottomPanel.getHeight()).setDuration(animationDuration);
}
},
EXPANDED {
#Override
public void moveTo(View topPanel, View bottomPanel, long animationDuration) {
topPanel.animate().translationY(-bottomPanel.getHeight()).setDuration(animationDuration);
bottomPanel.animate().translationY(0).setDuration(animationDuration);
}
};
public abstract void moveTo(View topPanel, View bottomPanel, long animationDuration);
}
Usage of this would be as follows:
State newState = State.EXPANDED;
newState.moveTo(topPanel, bottomPanel, 200);

Left-right arrow indicators over a ViewPager

I want to show left and right arrows over my ViewPager, to indicate swiping.
I added two ImageButtons over the ViewPager-element but those areas then block the ViewPager from triggering the "swiping".
I also want presses on those arrows to trigger the fragment to change accordingly.
In short: The ImageButtons should not interfere with swiping but they should register pressing.
How can I achieve this?
Thanks!
The code below worked for me perfectly well.
NB: Use FrameLayout as it allows overlapping views
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="200dp" />
<ImageButton
android:id="#+id/left_nav"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical|left"
android:src="#drawable/ic_chevron_left_black_24dp" />
<ImageButton
android:id="#+id/right_nav"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical|right"
android:src="#drawable/ic_chevron_right_black_24dp" />
</FrameLayout>
The following part I used to handle ImageButton's click events
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
leftNav = (ImageButton) view.findViewById(R.id.left_nav);
rightNav = (ImageButton) view.findViewById(R.id.right_nav);
// Images left navigation
leftNav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int tab = viewPager.getCurrentItem();
if (tab > 0) {
tab--;
viewPager.setCurrentItem(tab);
} else if (tab == 0) {
viewPager.setCurrentItem(tab);
}
}
});
// Images right navigatin
rightNav.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int tab = viewPager.getCurrentItem();
tab++;
viewPager.setCurrentItem(tab);
}
});
Output
No need to manage the current index for this or to handle any swiping manually. Simply call method viewPager.arrowScroll(int direction) method on the click events of left and right arrows.
In a nutshell follow these 2 simple steps:
Implement 2 ImageViews/ImageButtons/Buttons for left and right arrows.
On clicking them, call:
a) if left arrow is clicked - viewPager.arrowScroll(View.FOCUS_LEFT);
b) if right arrow is clicked - viewPager.arrowScroll(View.FOCUS_RIGHT);
Implement left & right arrow buttons in your fragment. Then register their onClick in your activity and call viewpager's arrowScroll method to scroll the viewPager programmatically.
public void onRightClick(View view) {
viewPager.arrowScroll(ViewPager.FOCUS_RIGHT);
}
public void onLeftClick(View view) {
viewPager.arrowScroll(ViewPager.FOCUS_LEFT);
}
Create a method to toggle left/right arrow visibility in your fragment.
public void toggleArrowVisibility(boolean isAtZeroIndex, boolean isAtLastIndex) {
if(isAtZeroIndex)
leftBtn.setVisibility(View.INVISIBLE);
else
leftBtn.setVisibility(View.VISIBLE);
if(isAtLastIndex)
rightBtn.setVisibility(View.INVISIBLE);
else
rightBtn.setVisibility(View.VISIBLE);
}
Now implement ViewPager.OnPageChangeListener in your activity. Use SmartFragmentStatePagerAdapter to keep track of registered fragments in memory.
#Override
public void onPageSelected(int position) {
MyFragment fragment = (MyFragment) smartAdapter.getRegisteredFragment(position);
fragment.toggleArrowVisibility(position == 0, position == list.size() - 1);
}
Instead of using ImageButtons for displaying the arrows, I now use ImageViews because they pass on any touch events to the layer underneath.
Then, I put transparent Buttons on the fragments themselves instead, that way they won't block the ViewPagers swiping behaviour but they will fire onClick Events!
First use relative layout as your parent layout
second then add view pager inside it with match parent attribute on it
third take two image buttons over the view pager but in under the hierarchy of parent layout
give them center vertical as a gravity and keep their side as right and left as per your requirement
fourth write functional code for buttons
fifth take static counter to get current view pager page
on left and right button set minus and plus the view pager counter resp. and according to that show data in view pager
this is the simple logic for code you can search it on google you will easily get it

ListView inside ViewPager won't scroll when applying a PageTransformer

I have a ViewPager in which the pages contain ListViews.
Everything works fine and my viewPAger as well as ListViews work as expected : it is possible to swipe from page to page, and the listviews scroll vertically as they should.
Now I wanted to add a PageTransformer to smooth out paging anbd I used the ZoomOutPageTransformer offered in the google docs.
Now I have a nice animation when swiping between views but the Lists are not scrollable anymore.
Here's the code :
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
LayoutInflater inflater = LayoutInflater.from(getActivity());
viewPager = (ViewPager) view.findViewById(R.id.bookMenuPager);
viewPager.setPageTransformer(false, new ZoomOutPageTransformer());
pagerAdapter = new MenuPagerAdapter();
viewPager.setAdapter(pagerAdapter);
}
class MenuPagerAdapter extends PagerAdapter{
#Override
public int getCount() {
return 3; //change this as needed
}
#Override
public boolean isViewFromObject(View view, Object o) {
return view.equals( o );
}
#Override
public Object instantiateItem(ViewGroup collection, int position) {
LayoutInflater inflater = (LayoutInflater) collection.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(position == 0){
if(!rootMenuAdded){
viewPager.addView(rootMenucont, 0);
rootMenuAdded = true;
}
return rootMenucont;
}else if(position == 1){
if(!level1MenuAdded){
viewPager.addView(level1MenuCont, 0);
level1MenuAdded = true;
}
return level1MenuCont;
}else if(position == 2){
if(!level2MenuAdded){
viewPager.addView(level2MenuCont, 0);
level2MenuAdded = true;
}
return level2MenuCont;
}
//we got a problem houston
return null;
}
}
and the layout for a page :
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/level1MenuCont"
android:layout_height="match_parent"
android:layout_width="match_parent"
>
<ListView
android:id="#+id/level1Menu"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#f02bb6"
>
</ListView>
</RelativeLayout>
What can I do to have my lists scrolling as expected ? What does the PageTransformer break in my ListView so that it wont scroll anymore?
Is this a known bug?
Thanks for any help :)
I think I have found a workaround for this issue.
After some investigation, I think this only happens if you apply a PageTransformer that changes the coordinates of the Views so they are all on top of each other (the two example transformers do exactly this).
When you swipe in the direction such as the NEW VIEW has a Z-index LOWER than the OLD VIEW (normally a swipe backwards), what happens with those transformers is that the OLD VIEW is on top of the NEW VIEW, with Alpha==0, and is the one that later on gets the "ghost" touches.
Unfortunately, the solution by #ngatyrauks bringToFront() didn't work for me (although it definitely should).
However, I have tweaked the transformer so invisible views are changed its visibility to "GONE". And this does the trick.
I have yet to investigate if this Visibility change has any side effects (A GONE view will return null and zeros in layout etc, so maybe this breaks other things inside ViewPager), but so far it's working perfect.
I post here a tweaked DepthPageTransformer (the same in the docs) with these changes. Hope it helps anybody!
package com.regaliz.gui.fx;
import android.util.Log;
import android.view.View;
import android.support.v4.view.ViewPager;
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final String TAG="DepthTransformer";
private static float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
Log.d(TAG, "VIew "+view+" Position: "+position);
if (position <= -1) { // [-Infinity,-1) ] ***
// RLP> I Changed to include "-1" as well: When position is -1, the view is not visible
// This page is way off-screen to the left.
view.setAlpha(0);
Log.d(TAG, "VIew "+view+" Position: "+position+", way left");
view.setVisibility(View.GONE);
} 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);
if (position==0) {
Log.d(TAG, "View "+view+" focused now?");
}
if (view.getVisibility()!=View.VISIBLE)
view.setVisibility(View.VISIBLE);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
// I THINK THIS IS WHAT BREAKS EVERYTHING
// ViewPager normally has the views one after another, but this makes all views on top
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);
if (position==1) {
Log.d(TAG, "View "+view+" invisible now?");
view.setVisibility(View.GONE);
// we totally hide the view. This seems to solve focus issue
} else {
if (view.getVisibility()!=View.VISIBLE)
view.setVisibility(View.VISIBLE);
}
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
// we totally hide the view. This seems to solve focus issue
// I have to check for strange side-effects, but so far I found none :)
view.setVisibility(View.GONE);
Log.d(TAG, "VIew "+view+" Position: "+position+", way right");
}
}
}
Here is the detail of the reason
after 4.1 that the framework respects a custom child drawing order as implied Z-ordering for dispatching touch events. If your views overlap after this page transformation they may not receive touch events in the expected order on older platform versions. Check which view is receiving the touch events to be certain.
If this is what you are seeing you have a few options:
Enforce the desired ordering as you add/remove child views in your PagerAdapter
Remove the X translation applied by the PageTransformer when a page is no longer fully visible - i.e. the "position" parameter reports a full -1 or 1.
And here is my solution
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position <= -1 || position >= 1) { // [-Infinity,-1) ] ***
// [-Infinity,-1] or [1,+Infinity]
// This page is way off-screen to the left or way off-screen to the right.
view.setAlpha(0);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} 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);
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);
}
}
ref link: https://code.google.com/p/android/issues/detail?id=58918
I don't know if you got this working, but I have the same issue, with a PageDepthTransformer. I'm using a gridview though, the scrolling works, however my subsequent fragments seem to have focus and my top level Fragment doesn't register the correct onClick() events.
My work around for this was to add global layout listener to viewPager and bring the current view to the front
viewPager.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
View view = viewPager.getChildAt(currentFragmentPosition);
if (view != null) {
view.bringToFront();
}
}
)};
This seems like hackery to me, and I haven't quite got this working on rotation. But hopefully it might help you.

Categories

Resources