Question

This is my first post here and my first try to explain a coding problem in english.. So please stay gentle while reading this :).

I have two questions about the ViewPager.

First:

If I pass a List of Fragments to the PagerAdapter it will show the first Fragment in the List. Is it possible to modify this to be able to show the 2nd, 3rd... Fragment in the List first? Because the method setCurrentItem(page) will show the page after the first fragment was displayed by the PagerAdapter.

Second:

I tried to implement a pause between a dynamic ViewChange like this:

// pass the Fragments to pagerAdapter here which will show the first fragment

// loop for the other Fragments
handler.postDelayed(new Runnable(){
    public void run(){
       for(int i = 0; i < list.size(); i++){
            ViewPager.setCurrentItem(list.indexOf(i), true);
            // Set Pause here
       }
    }
}, 500);

The comment "set pause here" marks the location where I'm still trying to pause between the paging. But i don't know how to solve this. Because Thread.sleep isn't the real deal here.

The idea was to display the first Fragment with the PageAdapter. Then I use handler.postDelayed to delay the second page swipe. And in this I'm looping through all pages with a constant delay.

I would be really happy if someone could help me to find a solution for these.

Was it helpful?

Solution

For your first question, are you calling setCurrentItem(int, false)? If you just call setCurrentItem(int), the ViewPager will animate the transition if it has already been through its first layout with its current adapter. If that's not a solution, maybe consider initializing the ViewPager with visibility = "invisible" in your layout file (or alternatively make a call to setVisibility(View.INVISIBLE) prior to passing the fragment list to the PagerAdapter.) Then, after you call setCurrentItem, you can set the ViewPager back to visible using setVisibility(View.VISIBLE). I would think that setting the ViewPager up in onCreate and calling setCurrentItem(int, false) should prevent any animations from appearing, but I don't have time to test right now.

For the second problem, I think the part that is tripping you up is that the run method is going to block the entire UI thread while it's running, which means that the UI won't be able to update itself while you are looping through the items in the ViewPager.

In essence, you are calling Thread.sleep() on the UI thread. That may not be totally clear since it's inside the Runnable's run method unless you realize that you have posted a message to run on the Handler's Thread, which will be the UI thread if you created it in an Activity life cycle method using the default Handler() constructor. Instead, you want your posted Runnable to postDelayed a new message for the next time you want to change the current item in the ViewPager.

What I would do is something like the following (caveat - I haven't tested this):

Subclass Handler to add a method to continuously loop (I am assuming you are doing this as an inner class on the Activity that holds the ViewPager so you get access to the member variable containing the ViewPager. I'm calling that member variable mPager in the code below):

private Runnable mLoopingRunnable = new Runnable(){
    public void run() {
        int currentItem = mPager.getCurrentItem();
        int totalItems = mPager.getAdapter().getCount();
        int nextItem = (currentItem + 1) % totalItems;
        mPager.setCurrentItem(nextItem, true);
                handler.postDelayed(self, 500);
            }
        };

handler.postDelayed(mLoopingRunnable, 500);

If/when you want to stop looping (note that you'll need to keep a handle to the Runnable if you want to cancel it at some point):

handler.removeCallbacks(mLoopingRunnable);

Note that one advantage of changing calling setCurrentItem as I have above is that it won't interfere with the user swiping the ViewPager to move from one view to the next. If you just set the currentItem to some integer like you did in your loop, the behavior will appear somewhat strange when the user has interacted with the pager.

I would have guessed that there was be something to handle the looping automatically similar to ViewFlipper, but it's not readily apparent that there is from a cursory look at the ViewPager API.

OTHER TIPS

You should not stop the UI Thread with a sleep, because during that time you want be able to interact with anything in your app, if you want you can post another delay like the first one... or chained Asynctask...

What i do recommend you is using ViewFlipper that can hold Fragments or Views and iterate between them and also add some transitions with xml, pretty simple and works good.

viewFlipper.setAnimation(AnimationUtils.loadAnimation(this,
            R.anim.push_from_right_in));
// this animations are XML in res-> anim folder
viewFlipper.showPrevious(); // go to the next fragment in order

You can set a delay between each new animation....

viewFlipper.startFlipping();

And you can set a lot of things from the xml also, like the time between animations.

<ViewFlipper
    android:id="@+id/signup_layout_viewFlipper"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/headerFragment"
    android:flipInterval="1111" >

The animation that push the views:

<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:duration="300"
android:fromXDelta="100%"
android:fromYDelta="0%"
android:toXDelta="0%"
android:toYDelta="0%" />

Hope that helps :)

Regards

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top