【发布时间】:2016-02-26 04:00:42
【问题描述】:
我有一个以 this 示例为模型的 ViewPager,我在其中实现 ViewPager.PageTransformer:
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
view.setAlpha(1 - position);
view.setTranslationX(view.getWidth() * -position);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
view.setAlpha(0);
}
}
}
而且效果很好,正如上面链接中的深度页面转换器动画所示。
但是,它目前的工作方式是 right 的视图总是低于 left 的视图。当您向右滚动时,视图来自下方。向左滚动使当前视图位于新视图下方,新视图滑入顶部。
我想做的是让当前视图始终位于顶部,并让新视图(左或右)从后面/下方进入。
我已经尝试添加
view.bringToFront();
到if(position <= 0) 块,但没有任何变化。我也试过添加
view.bringToFront();
view.invalidate();
和
view.bringToFront();
((View)view.getParent()).invalidate();
一切都无济于事。这些与我能找到的similar SO posts 采用的方法相同,但他们都接受了答案,并且 cmets 说它们有效。但我的没有!
无论滑动方向如何,如何让当前视图始终位于最顶层?
编辑 1 - 附加细节
正如 cmets 中提到的,我需要知道是向右还是向左滑动才能获得双向的相同动画。
ViewPager 只有 三个 视图,它们显示为 VerticalViewPager,基于 this 帖子。
在 PageTransformer 中,我有以下内容:
@Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
view.setAlpha(0);
}
else if(position <= 0){
if(view == first){
view.setAlpha(1 - Math.abs(position));
view.setTranslationX(view.getWidth() * -position);
view.setTranslationY(0);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}else if(view == second){
view.setAlpha(1);
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
}else if(view == third){
// Never happen
}
}
else if (position <= 1) { // [0,1]
if(view == first){
// Never happen
}else if(view == second){
view.setAlpha(1);
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
}else if(view == third){
view.setAlpha(1 - position);
view.setTranslationX(view.getWidth() * -position);
view.setTranslationY(0);
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}
} else { // (1,+Infinity]
view.setAlpha(0);
}
}
其中first、second 和third 是View 类型并设置在PagerAdapter 内部:
@Override
public View instantiateItem(ViewGroup container, int position) {
if(position == 0){
... stuff ...
vvp.first = img;
... stuff ...
}else if(position == 1){
... stuff ...
vvp.second = img;
... stuff ...
}else if(position == 2){
... stuff ...
vvp.third = img;
... stuff ...
}
}
它有点被破解,但效果很好,并且得到了我正在寻找的功能。除了 bringToFront 不起作用的东西。但无论我使用原始帖子中的transformPage 代码,还是本次编辑中更全面的版本,它都不起作用。
仍然不确定如何使second(即三者的中间视图)始终位于顶部。我什至尝试了一个通用的
second.bringToFront();
在方法的顶部,但仍然没有。
编辑 2
刚刚尝试view.setZ()但遇到以下错误:
java.lang.NoSuchMethodError: android.view.View.setZ
所以那个选项也没有了。
编辑 3 - 解决方案
对于我对这个问题的解决方案,请参阅下面的答案(使用getChildDrawingOrder)。
话虽如此,我仍然无法让bringToFront 工作,如果你能弄清楚,我很乐意选择你的答案作为所选答案。
再次提前致谢。
【问题讨论】:
标签: android android-viewpager android-view bringtofront