Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
410 views
in Technique[技术] by (71.8m points)

android - 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 :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...