Alex Moiseenkov
Alex Moiseenkov

Reputation: 49

My fragmentClass get wrong page from ViewPager in medod onContextItemSelected

First. Sorry for my English.

I have Activity class with ViewPager as a field and a Fragment class. My activity is a host for a fragment. In Fragment I want to call context menu registered for ImageView. For that, I override 2 methods: onCreateContextMenu and onContextItemSelected.

Problem is:

How can I fix it?

Thank you.

Activity code

public class CrimePagerActivity extends FragmentActivity {
    private ViewPager mViewPager;
    private ArrayList<Crime> mCrimes;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


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

        mCrimes = CrimeLab.get(this).getCrimes();

        mViewPager.setOffscreenPageLimit(4);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mViewPager.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
        }
        FragmentManager fm = getSupportFragmentManager();
        mViewPager.setAdapter(new FragmentStatePagerAdapter(fm) {
            @Override
            public Fragment getItem(int position) {
                Crime crime = mCrimes.get(position);
                return CrimeFragment.newInstance(crime.getId());
            }

            @Override
            public int getCount() {
                return mCrimes.size();
            }
        });

        UUID crimeId = (UUID) getIntent().getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
        for (int i = 0; i< mCrimes.size(); i++){
            if (mCrimes.get(i).getId().equals(crimeId)){
                mViewPager.setCurrentItem(i);
                break;
            }
        }
    }
}

and fragment code

public class CrimeFragment extends Fragment {
  .......
  private ImageView mPhotoView;

  @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        ........
        View v = inflater.inflate(R.layout.fragment_crime, container, false);
        mPhotoView = (ImageView) v.findViewById(R.id.crime_imageView);
        registerForContextMenu(mPhotoView);
        return v;
    }

 .........

 @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        Log.i(TAG, mCrime.getTitle());
        switch (v.getId()) {
            case R.id.crime_imageView:
                if (mCrime.getPhoto() != null)
                    getActivity().getMenuInflater().inflate(R.menu.crime_photo_context, menu);
                break;
        }
    }


    @Override
    public boolean onContextItemSelected(MenuItem item) {
        Log.i(TAG, mCrime.getTitle());

        switch (item.getItemId()) {
            case R.id.menu_item_delete_photo:
                getActivity().deleteFile(mCrime.getPhoto().getFilename());
                PictureUtils.cleanImageView(mPhotoView);
                mCrime.setPhoto(null);
                return true;
        }
        return super.onContextItemSelected(item);
    }
}

Upvotes: 1

Views: 132

Answers (1)

Ritt
Ritt

Reputation: 3349

ViewPager.setOffscreenPageLimit(int);

This will prepare the pages at both sides to the left and right (neighbours).

By default it is 1.

So, in your case to get the current fragment created by the viewPager.

You can store the fragments when created in an SparseArray by overriding the instantiateItem() and destroyItem() callback of viewPager with position.

private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

@Override
public Object instantiateItem(ViewGroup container, int position) {
    Fragment fragment = (Fragment) super.instantiateItem(container, position);
    registeredFragments.put(position, fragment);
    return fragment;
}

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


public Fragment getFragment(int position) {
    return registeredFragments.get(position);
}

And where you want to get the current fragment, get it by using the getFragment() method by passing the position.

Upvotes: 0

Related Questions