应用PageTransformer时,ViewPager中的ListView不会滚动

时间:2013-06-20 20:32:52

标签: android android-listview android-viewpager

我有一个ViewPager,其中的页面包含ListViews。 一切正常,我的viewPAger和ListViews按预期工作:可以在页面之间滑动,列表视图按原样垂直滚动。

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

现在我在视图之间滑动时有一个很好的动画但是列表不再可滚动了。

以下是代码:

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

如何让我的列表按预期滚动? PageTransformer在我的ListView中打破了什么,以至于它不再滚动了? 这是一个已知的错误吗?

感谢您的帮助:)

3 个答案:

答案 0 :(得分:9)

我想我找到了解决此问题的方法。

经过一些调查后,我认为只有当您应用PageTransformer更改Views的坐标时才会发生这种情况,因此它们彼此重叠(两个示例变换器正是这样做的)。

当您按 NEW VIEW的Z-index低于OLD VIEW (通常向后滑动)的方向滑动时,这些变换器会发生的情况是OLD VIEW已打开新视图的顶部,Alpha == 0,是后来获得“幽灵”触摸的那个。

不幸的是,@ ngatyrauks bringToFront()的解决方案对我不起作用(虽然它肯定应该)。

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

我还没有调查此可见性更改是否有任何副作用(A 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");
                    }
                }
            }

答案 1 :(得分:2)

以下是原因的详细信息

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

     

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

     
      
  • 在PagerAdapter
  • 中添加/删除子视图时强制执行所需的排序   
  • 当页面不再完全可见时,删除PageTransformer应用的X平移 - 即&#34;位置&#34;参数报告完整的-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

答案 2 :(得分:0)

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

我的工作是为viewPager添加全局布局监听器并将当前视图添加到前面

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

    @Override
    public void onGlobalLayout() {

        View view = viewPager.getChildAt(currentFragmentPosition);

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

这对我来说似乎很麻烦,而且我还没有完成旋转工作。但希望它可以帮助你。