I have a flag/bookmark button in the Action Bar that I want to be toggled on or off depending which Fragment is in view of the ViewPager.
If the user flags a fragment in the ViewPager, it will be set to enabled. When the user swipes to the next one, I want the action bar button to update to unflagged. Now, I'm able to change the state of the button by having two menu items and hide one, show one when clicked.
Here's the code in my Activity to toggle the Action Bar button:
public boolean onOptionsItemSelected(MenuItem item) {
int currentItem = mPager.getCurrentItem();
switch (item.getItemId()) {
case R.id.menu_flag:
mFlagged = true;
supportInvalidateOptionsMenu();
return true;
case R.id.menu_unflag:
mFlagged = false;
supportInvalidateOptionsMenu();
return true;
}
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item_flag = menu.findItem(R.id.menu_flag);
MenuItem item_unflag = menu.findItem(R.id.menu_unflag);
if (mFlagged) {
//If flagged
//Show flagged item
item_flag.setVisible(false).setEnabled(false);
item_unflag.setVisible(true).setEnabled(true);
item_flag.isVisible();
} else {
//If not flagged
//Show unflagged icon
item_flag.setVisible(true).setEnabled(true);
item_unflag.setVisible(false).setEnabled(false);
}
return super.onPrepareOptionsMenu(menu);
}
The problem I'm having is that I can't access the menu item, save & restore the state of the button, i.e. if it's flagged or not from the fragment or the FragmentPagerAdapter.
How can I do this? Which level should I be accessing the Action Bar; Activity, PagerAdapter or the Fragments?
Registering a ViewPager.OnPageChangeListener on your ViewPager should do the trick. Then, override onPageSelected(int pageNum) to receive callbacks when a page changes.
public void onPageSelected(int pageNum) {
supportInvalidateOptionsMenu();
}
Related
I have an Actionbar displayed on my maps fragment to which I have added a zoom-in button. When selected I would like to replace it with a zoom-out button.
When zoom-in is selected the it is obviously pases in to onOptionsItemSelected as the menu item, so it is easy to set it's attributes like this: viewZoomIn.setVisibility(viewZoomIn.GONE); My problem is, how do I get a reference to the zoom-out button on the action bar to set it as as I would like to viewZoomOut.setVisibility(viewZoomOut.VISIBLE);?
I thought I may be able to store the zoom-in and zoom-out views as instance variables and capture them when I inflate the Actionbar, like this:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
viewZoomIn = findViewById(R.id.zoom_in);
viewZoomOut = findViewById(R.id.zoom_out);
return super.onCreateOptionsMenu(menu);
This does not work.
Any help on getting hold of thes buttons, or advice on a better way of toggling my zoom-in/zoom-out buttons would be appreciated.
It probably shows, but I am pretty new to Java, so it would be preferable is any assistance were communicated in a simple manner.
Thank you.
You have to apply your visibility logic in onPrepareOptionsMenu(Menu) not in onCreateOptionsMenu(Menu) if you want to toggle MenuItem state.
private boolean currentlyZoomedIn;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// called the first time and after each "invalidateOptionsMenu()"
// if tha Activity is in the "zoomedIn" state, the zoomOut button will be visible
menu.findItem(R.id.zoom_in).setVisible(!currentlyZoomedIn);
menu.findItem(R.id.zoom_out).setVisible(currentlyZoomedIn);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.zoom_in:
// do your logic when zoom_in is clicked
currentlyZoomedIn = true;
break;
case R.id.zoom_out:
// do your logic when zoom_out is clicked
currentlyZoomedIn = false;
break;
}
// force the redraw of the menu
invalidateOptionsMenu();
return super.onOptionsItemSelected(item);
}
By the way, I suggest you to use only one button and move your logic only in onOptionsItemSelected(MenuItem) to avoid an instance variable and the call to invalidateOptionsMenu() in a way like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// zoom_out_in_id is the id for the common button
if (item.getItemId() == R.id.zoom_out_in_id) {
// get the curren title
final CharSequence title = item.getTitle();
// if the current title is the one of zoom_in button, you have to change its infos to zoom_out ones
if (title.equals("zoom_in_title")) {
// do your logic when zoom_in is clicked
item.setIcon(R.drawable.zoom_out_icon);
item.setTitle("zoom_out_title");
} else if (title.equals("zoom_out_title")) {
// do your logic when zoom_out is clicked
item.setIcon(R.drawable.zoom_in_icon);
item.setTitle("zoom_in_title");
}
}
return super.onOptionsItemSelected(item);
}
I have this code
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
openSearch();
return true;
}
});
into onCreate( ) of my Activity.
OpenSearch function call opens up google now like search view. This only happens when the user clicks on the search action item in the toolbar. In my case I want the search view to open up automatically when the activity starts. How can this menu item click be done programmatically.
I can't call openSearch directly because it needs the menu to be created.
Is there there any callbacks informing that action menus have been created ?
You can try something like this :
tollbarLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
tollbarLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
tollbar.performclick();
}
}
});
I am using fixed tabs + swipe inside a FragmentActivity. I have added a menu in action bar. I want that when the menu is clicked it should open class based on the current tab that is selected.
static TabHost myTabs;
-
-
-
myTabs = getTabHost();
This shows an error asking me if it shouls create a method called getTabHost(). I am assuming its because I am using FragmentActivity instead of Activity. So how do I know which tab is selected?
EDIT
As told below I have done this
#Override
public void onAttachFragment(Fragment fragment){
super.onAttachFragment(fragment);
tabValue=fragment.getId();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.one, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (tabValue) {
case 0:
Toast.makeText(BarcodeActivity.this, "HELLO", Toast.LENGTH_LONG).show();
case 1:
Intent i = new Intent(BarcodeActivity.this, NewCodeAdder.class);
startActivity(i);
break;
}
return true;
}
But still nothing happens when I click on the menu add option.
Check this out, it has everything from id to finding names of tabs:
Get the current fragment object
I'm trying to change the option menu after an item on the menu is selected.
This is what I tried:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(refresh) {
menu.clear();
menu.add(0, Menu.FIRST, 0, "Changed item");
}
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.refresh)
{
refresh = true;
closeOptionsMenu();
invalidateOptionsMenu();
openOptionsMenu();
}
return super.onOptionsItemSelected(item);
}
But I get:
W/InputManagerService(192): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy#4147c778
and the code is not working..
Any idea?
the menu will close and not reopen, only if i reclick on the menu button i see the new value
I don't know of anyway to keep the options menu open after an item has been selected, however you can reopen it automatically with a Handler and Runnable.
Create a couple new field variables:
private Handler handler = new Handler();
private Runnable reopenMenu = new Runnable() {
#Override
public void run() {
openOptionsMenu();
}
};
And inside onOptionsItemSelected() use:
if(item.getItemId() == R.id.refresh)
{
refresh = true;
invalidateOptionsMenu(); // This is only necessary for changing an ActionBar
handler.postDelayed(reopenMenu, 100);
}
(Notice I removed the calls to close and open the menu.)
Lastly you should set refresh = false; in onPrepareOptionsMenu() since you only need to make the change once.
It might be easier to have the second button already on the menu but visibility set to GONE, and then make it visible when you need.
MenuItem = menu.findItem(R.id.menuItem);
MenuItem.setVisible(false);
I am having trouble getting the following piece of code to work out. I have a viewpager with 3 fragments, and I want a search icon to only show up on one. I started off trying to add the search function by the fragment, but the rendering of the menu item was slow when swiping to that page. I am now on the part to add the search icon to the activity, and then just hide or show depending on which viewpager page is active, but the following is not working:
public class MyApp extends FragmentActivity implements
FragmentTeams.FragmentNotification,ViewPager.OnPageChangeListener,
OnNavigationListener{
...
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
menuSearch = menu.findItem(R.id.menu_search);
mSearchView = new SearchView(this);
menuSearch.setActionView(mSearchView);
menuSearch.setVisible(false);
return true;
}
#Override
public void onPageSelected(int pageNum) {
if(pageNum== 1){
ActionBar actionBar = MyApp.this.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
menuSearch.setVisible(true);
invalidateOptionsMenu();
}else{
ActionBar actionBar = MyApp.this.getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
menuSearch.setVisible(false);
invalidateOptionsMenu();
}
}
While the above does (appear to) create and hide the icon at onCreateOptionsMenu, it is not reenabled when moving to
pageNum ==1
Can anyone give me some insight as to why this may be happening?
invalidateOptionsMenu make the system calls the method onPrepareOptionsMenu, so you can override this method as follows:
public boolean onPrepareOptionsMenu(Menu menu) {
int pageNum = getCurrentPage();
if (pageNum == 1) {
menu.findItem(R.id.menu_search).setVisible(true);
}
else {
menu.findItem(R.id.menu_search).setVisible(false);
}
}
public void onPageSelected(int pageNum) {
invalidateOptionsMenu();
}
You can implement onCreateOptionsMenu() in your Fragment and set 'setHasOptionsMenu(true)' for the fragment
a possible solution for this problem would be inflating your custom menu inside the activity hosts your ViewPager and getting a menu reference as below:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.custom_menu, menu);
customMenu = menu;
return super.onCreateOptionsMenu(menu);
}
after that you can easily hide/show the menu's items without any delay inside onPageSelected method as below:
#Override
public void onPageSelected(int position) {
switch (position) {
case 0: {
customMenu.getItem(0).setVisible(false);
break;
}
case 1: {
customMenu.getItem(0).setVisible(true);
break;
}
}
I used Nermeen's answer and managed to get it without any delay.
I don't inflate anything in onCreateOptionsMenu, but use it to get a reference to the menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
customMenu = menu;
return super.onCreateOptionsMenu(menu);
}
Then, in onPrepareOptionsMenu(), I call the viewpager getCurrentItem() (should be something like viewPager.getCurrentItem()), call invalidateOptionsMenu() and inflate whatever menu I want in that page using the customMenu reference I created in onCreateOptionsMenu().