2

我有一个 ViewPager,其中的页面包含 ListViews。一切正常,我的 viewPAger 和 ListViews 按预期工作:可以从一个页面滑动到另一个页面,并且 listviews 可以垂直滚动。

现在我想添加一个 PageTransformer 来平滑分页,并且我使用了谷歌文档中提供的ZoomOutPageTransformer

现在,在视图之间滑动时我有一个不错的动画,但列表不再可滚动。

这是代码:

@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;
    }
 }

和页面的布局:

<?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> 

我该怎么做才能让我的列表按预期滚动?我的 ListView 中的 PageTransformer 中断了什么,使其不再滚动?这是一个已知的错误?

谢谢你的帮助 :)

4

3 回答 3

10

我想我已经找到了解决这个问题的方法。

经过一番调查,我认为只有当你应用 aPageTransformer来改变坐标时才会发生这种情况,Views所以它们都在彼此之上(两个示例转换器正是这样做的)。

当您向新视图的方向滑动时,例如新视图的 Z 索引低于旧视图(通常是向后滑动),这些转换器发生的情况是旧视图位于新视图之上,Alpha== 0,是后来得到“鬼”接触的那个。

不幸的是,@ngatyrauks 的解决方案bringToFront()对我不起作用(尽管它绝对应该)。

但是,我已经调整了变压器,因此不可见views将其可见性更改为“GONE”。这就是诀窍。

我尚未调查此可见性更改是否有任何副作用(GONE视图将返回null并在布局等中归零,所以这可能会破坏内部ViewPager的其他内容),但到目前为止它运行良好。

我在这里发布了DepthPageTransformer这些更改的调整(在文档中相同)。希望它可以帮助任何人!

            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");
                    }
                }
            }
于 2014-03-27T15:52:33.017 回答
2

这里是详细的原因

在 4.1 之后,框架尊重自定义子绘图顺序作为调度触摸事件的隐含 Z 顺序。如果您的视图在此页面转换后重叠,则它们可能无法在旧平台版本上按预期顺序接收触摸事件。检查哪个视图正在接收触摸事件以确定。

如果这是您所看到的,您有几个选择:

  • 在 PagerAdapter 中添加/删除子视图时强制执行所需的排序
  • 当页面不再完全可见时,移除由 PageTransformer 应用的 X 平移 - 即“位置”参数报告完整的 -1 或 1。

这是我的解决方案

  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);

    } 
}

参考链接:https ://code.google.com/p/android/issues/detail?id=58918

于 2015-05-03T23:39:25.267 回答
0

我不知道你是否能正常工作,但我有同样的问题,PageDepthTransformer。我使用的是gridview,滚动工作,但是我的后续片段似乎有焦点,我的顶级片段没有注册正确的onClick()事件。

我的解决方法是将全局布局侦听器添加到 viewPager 并将当前视图放在前面

viewPager.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {

        View view = viewPager.getChildAt(currentFragmentPosition);

        if (view != null) {
            view.bringToFront();
        }
    }
)};

这对我来说似乎很骇人听闻,而且我还没有完全完成轮换工作。但希望它可以帮助你。

于 2013-10-21T01:51:24.740 回答