简体   繁体   中英

Android FragmentStatePagerAdapter implementation

I am implementing android ViewPager. Here is the sample code for that

public class MyAdapter extends FragmentStatePagerAdapter {
        public MyAdapter(FragmentManager fragmentManager) {
            super(fragmentManager);
        }

        @Override
        public int getCount() {
            return 5;
        }

        @Override
        public Fragment getItem(int position) {
            return SampleItemFragment.init(position);
        }
    }

Layout file

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"/>

Fragment Code

public class SampleItemFragment extends Fragment {

    int fragVal;
    private ImageButton buyButton;
    private boolean mShowingBack;

    static SampleItemFragment init(int val) {
        SampleItemFragment truitonFrag = new SampleItemFragment();
        // Supply val input as an argument.
        Bundle args = new Bundle();
        args.putInt("val", val);
        truitonFrag.setArguments(args);
        return truitonFrag;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        fragVal = getArguments() != null ? getArguments().getInt("val") : 1;
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        return inflater.inflate(R.layout.fragment_samplecard_item, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        buyButton = (ImageButton)getActivity().findViewById(R.id.buyButton);
        buyButton.setOnClickListener(buyButtonListener);
    }

    View.OnClickListener buyButtonListener = new View.OnClickListener() {
        @Override
        public void onClick(View view)
        {
            if (mShowingBack) {
                getFragmentManager().popBackStack();
                mShowingBack = false;
                return;
            }

            // Flip to the back.

            mShowingBack = true;

            // Create and commit a new fragment transaction that adds the fragment for the back of
            // the card, uses custom animations, and is part of the fragment manager's back stack.

            getFragmentManager()
                    .beginTransaction()

                            // Replace the default fragment animations with animator resources representing
                            // rotations when switching to the back of the card, as well as animator
                            // resources representing rotations when flipping back to the front (e.g. when
                            // the system Back button is pressed).
                    .setCustomAnimations(
                            R.animator.from_middle,R.animator.to_middle,R.animator.to_middle,R.animator.from_middle)

                            // Replace any fragments currently in the container view with a fragment
                            // representing the next page (indicated by the just-incremented currentPage
                            // variable).
                    .replace(R.id.placeholderItem, new SampleCardBackFragment())

                            // Add this transaction to the back stack, allowing users to press Back
                            // to get to the front of the card.
                    .addToBackStack(null)

                            // Commit the transaction.
                    .commit();
        }
    };
}

I have a buy button in each fragment, when clicked I am replacing the fragment with a new fragment. That works fine. But my issue is say I have 4 fragments loaded to the view pager. When I click the button always the content of the first fragment is changes.

When I am clicking the button inside the third fragment I am expecting that the fragment replace occurs on the third fragment, but always for all button click the replace occurs in the first fragment.

Whats going wrong here?

Thanks.

You'd better not mess with the FragmentManager from inside each fragment. You should for instance, when you press BUY, it will change the model (a flag or data somewhere) and you then trigger an update on your MyAdapter by simply calling the notifyDataSetChanged() this should be enough to trigger the recreation of the fragments in a proper way.

Ideally you could reuse the same instance of the already created fragment, like this you would just change the state of the current view, but it depends on what you want to do, if it's a totally different thing, i would do the MyAdapter.notifyDataSetChanged() approach.

You're probably wondering how to get the MyAdapter instance..you could for instance, make an accessor method on your Activity..and from the onClick() in your Fragment you would do:

  // after changing your model with the new state
 ((MyActivity) getActivity()).getMyAdapter().notifyDataSetChanged(); 

You are using ViewPager with ViewPagerAdapter. Then you should switch fragment through ViewPager and ViewPagerAdapter because the fragments' states are kept by them. Here is ViewPager.setCurrentItem API . You can use this API to switch fragment inside fragment.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM