Wrong Fragment in Viewpager Receives Oncontextitemselected Call

Wrong fragment in ViewPager receives onContextItemSelected call

So this is some sort of idiotic design decision by Google or something that has just gone totally unconsidered. The simplest way to work around this is to wrap the onContextItemSelected call with an if statement like this:

if (getUserVisibleHint()) {
// Handle menu events and return true
} else
return false; // Pass the event to the next fragment

The compatibility library in ActionBarSherlock 3.5 had a hack like this.

My fragmentClass get wrong page from ViewPager in medod onContextItemSelected

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.

onContextItemSelected called twice for fragment

This solution on this question fixed my issue:

How to handle onContextItemSelected in a multi fragment activity?

using getUserVisibleHint() in onContextItemSelected.

onContextItemSelected() not called when a listview is embedded in a ViewPager

I hacked some code together and had a similar problem. I registered the ListView in Fragment 2 for context menu and unregistered Fragment 1. Yet somehow onContextItemSelected() was being called on Fragment 1.

Turns out that when the FragmentManager dispatches a ContextItemSelected event, it calls onContextItemSelected() on every single Fragment it knows about until one of them returns true. So in your onContextItemSelected(), you have to check if the fragment is the current page in the ViewPager; if it isn't, return false. This can be one source of problems.

See this SO question: Wrong fragment in ViewPager receives onContextItemSelected call

Hope that's helpful

How to handle onContextItemSelected in a multi fragment activity?

I found an alternative. It does not change anything on my problem above, but it makes it pointless.

I have remove the context menu completely from my application. Instead I capture the longclick on a list item and change the visible buttons of the action bar in this moment.
From the user point of view this is much more tablet like as a context menu.

In backward compatible applications the actionbar does not exist. So I've decided to build my own (kind of toolbar on top) for the devices pre Honeycomb.

If you would like to stay with the context menu, I did not find a better solution as the workaround I've mentioned above.

onContextItemSelected is not called in Fragment

I solved my problem.

I change the implementation of this method: onContextItemSelected to setOnMenuItemClickListener inside of onCreateContextMenu method as the following code:

@Override   
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId()==R.id.lvCentrais){
menu.setHeaderTitle(R.string.operacoes);
String[] menuitems = getResources().getStringArray(R.array.menu_acoes_central);
for (int i=0;i<menuitems.length;i++){
menu.add(Menu.NONE,i,i,menuitems[i]);
}
for (int i=0;i<menu.size();i++){
menu.getItem(i).setOnMenuItemClickListener(new OnMenuItemClickListener() {

@Override
public boolean onMenuItemClick(MenuItem item) {
int menuindex = item.getItemId();

switch (menuindex) {
case 0:
Toast.makeText(getView().getContext(), "Rename", Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(getView().getContext(), "Remove", Toast.LENGTH_SHORT).show();
break;

default:
Toast.makeText(getView().getContext(), "invalid option!", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
}
}

Thanks for all help!

Variable's address is different inside onContextItemSelected

The root cause of my issue was that the Fragment was being created twice by the Action Bar tab manager code. The OnContextItemSelected method was using the 'encounter' variable from the 2nd instance of the Fragment, whereas the other source was using the copy from the first instance. Resolved using this post: Fragment onCreateView and onActivityCreated called twice

How to copy the text in the current TextView in ViewPager

After a lot of searching and I dont know how many trial and error, I found a solution for my problem.

Using "getUserVisibleHint()" or "getGroupId()" methods, I couldnot get the current textview's text.
I used "text = tvTextView.getText().toString();" in onContextItemSelected or in onCreateView methods, but it didnot work.

@Override
public boolean onContextItemSelected(MenuItem item) {

if( ! getUserVisibleHint() )
{
return false;
}

// this is not working
text = tvTextView.getText().toString();

Then I tried making setText and getText methods for fragment and getting the text in onContextItemSelected method using getText method. It works great!

First I added two methods to Fragment:

public String getText() {
return mText;
}

public void setText(String text) {
mText = text;
}

In onCreateView I set the text

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment, parent, false);

tvTextView = (TextView) v.findViewById(R.id.tvTextView);
registerForContextMenu(tvTextView);

String tvText = tvTextView.getText().toString();

// I set the text
setText(tvText);

Then in onContextItemSelected I get it using getText

@Override
public boolean onContextItemSelected(MenuItem item) {

if( ! getUserVisibleHint() )
{
return false;
}

// I get the text
mCopyText = getText();

Both "getUserVisibleHint()" or "getGroupId()" methods works great in this way. I hope this help other people.



Related Topics



Leave a reply



Submit