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
Display a Part of the Webpage on the Webview Android
Display Fb Profile Pic in Circular Image View in Application
Custom Font in Android Listview
How to Use Mkfifo Using Android's Ndk
Android Getorientation Azimuth Gets Polluted When Phone Is Tilted
Android - Taking Photos and Saving Them with a Custom Name to a Custom Destination via Intent
Cli on Dalvikvm Fails on Jni Lib
Android Access to Remote SQL Database
Writing/Reading Files To/From Android Phone's Internal Memory
Android Draw Route on a Mapview with Twoo Poi-S
How to Read Text File in Android
Elevation on Android Lollipop Not Working
Android - Detecting Application Launch from Home or History
Android Datepickerdialog: Set Min and Max Date for Selection
How to Display Map (Google) on a Phonegap Android Application
Nested Fragments Disappear During Transition Animation
Android Navigation Drawer on Top Actionbar
Android: Sample Code to Connect to Vpn in Android 4.0 Using Vpnservice API