1

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:

  • When onCreateContextMenu is called I get the correct page (that on the screen now).
  • But when onContextItemSelected is called I get another page (this depend on what parameter is set in ViewPager.setOffscreenPageLimit(int)). For example, if it set 3, the returned page will be those, that on 3 positions to the left or to the right from current that on the screen.

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);
    }
}
Alex Moiseenkov
  • 49
  • 1
  • 10
  • You should use a ViewPager.OnPageChangedListener, and call into the current Fragment in order to call `registerForContextMenu()` each time the user swipes to that Fragment (remove the call from `onCreateView()`). See here for an example of this approach: http://stackoverflow.com/a/36504458/4409409 – Daniel Nugent Jun 11 '16 at 17:57

1 Answers1

0
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.

Ritt
  • 3,181
  • 3
  • 22
  • 51
  • I know it. The question is how to make ViewPager return current page ( not neighbours) in my Fragment class method onContextItemSelected() – Alex Moiseenkov Jun 11 '16 at 17:42