John Ernest Guadalupe
John Ernest Guadalupe

Reputation: 6639

Why does my ViewPager always display the second image instead of the first?

I am using a ViewPager in my FragmentActivity. Now, whenever my Activity fires up I pass in the position value into the newinstance method of my fragment. From there my fragment will now select the resource id of the drawable and set it as its background.

My Fragment Activity

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.LayoutParams;
import android.view.ViewGroup;
import android.view.Window;

public class HowToActivity extends FragmentActivity {

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.slide_out_bottom, R.anim.slide_in_top);

    }


    private ViewPager mViewPager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);  // remove title

        mViewPager = new ViewPager(this);
        mViewPager.setId(R.id.viewPager_howto);

        setContentView(mViewPager);

        getWindow().setLayout(LayoutParams.MATCH_PARENT /* width */ , LayoutParams.MATCH_PARENT /* height */);

        FragmentManager fm = this.getSupportFragmentManager();
        mViewPager.setAdapter(new FragmentStatePagerAdapter(fm){

            @Override
            public void setPrimaryItem(ViewGroup container, int position,
                    Object object) {
                super.setPrimaryItem(container, position, object);
            }

            @Override
            public int getCount() {
                return 3;

            }
            @Override
            public Fragment getItem(int position) {
                 return HowToFragment.newInstance(position);
            }

        });
    }

}

My Fragment

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class HowToFragment extends Fragment {

    private static int image_pos;
    private int[] image_id = {R.drawable.image_1, R.drawable.image_2, R.drawable.image_3};

    public static Fragment newInstance(int pos){
        image_pos = pos;
        return new HowToFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_how_to_image, container, false);
        v.setBackgroundResource(image_id[image_pos]);
        return v;
    }

}

It always shows the image_2.png instead of the image_1 on start up. Then you need to swipe all the way to image_3 or the 2 position for it to fix the image_1 on the 0 position. Swiping back and forth from 0 and 1 will just show image_2 in each fragment.

Any ideas what I did wrong?

Upvotes: 0

Views: 1147

Answers (2)

Khawar Raza
Khawar Raza

Reputation: 16120

The reason is that adapter not only creates the fragment that is visible but also preloads the right and left fragments. Don't make the position field static. Use it as data member and set that pos value before returning the fragment.

Upvotes: 1

Juangcg
Juangcg

Reputation: 1048

You can not make that variable static

private static int image_pos;

All the fragments are using the same so you always see the second one when you create it.

FG[0] newInstance -> image_pos=0;
FG[1] newInstance -> image_pos=1;

and when the fragments are gonna create the view:

FG[0] onCreateView -> value of image_pos=1;
FG[1] onCreateView -> value of image_pos=1;

Make this instead:

private int image_pos;
private int[] image_id = {R.drawable.image_1, R.drawable.image_2, R.drawable.image_3};

public static Fragment newInstance(int pos){
    HowToFragment fg = new HowToFragment();
    fg.image_pos = pos;
    return fg;
}

Also you can define the array with the images in the adapter and just pass the Id on the fragment create method.

Upvotes: 2

Related Questions