Listview Inside Viewpager Won't Scroll When Applying A Pagetransformer
Solution 1:
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;
publicclassDepthPageTransformerimplementsViewPager.PageTransformer {
privatestaticfinal String TAG="DepthTransformer";
privatestaticfloatMIN_SCALE=0.75f;
publicvoidtransformPage(View view, float position) {
intpageWidth= 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);
} elseif (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);
} elseif (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)floatscaleFactor= 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");
}
}
}
Solution 2:
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
publicvoidtransformPage(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);
} elseif (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);
} elseif (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
Solution 3:
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(newOnGlobalLayoutListener() {
@OverridepublicvoidonGlobalLayout() {
Viewview= 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.
Post a Comment for "Listview Inside Viewpager Won't Scroll When Applying A Pagetransformer"