I create base activity with actionbar menu functional and extended another activities from it.
public class BaseActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
...
return true;
}
}
Now I want to add some buttons to the actionbar in some activities. How can i add elements to actionbar and use element from base activity?
You can do that as simple as in BaseActivity just don't forget to call super.onCreateOptionsMenu().
main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_help"
android:icon="#drawable/ic_action_help"
android:title="#string/action_help" />
</menu>
home.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_new"
android:icon="#drawable/ic_action_new"
android:title="#string/action_new" />
</menu>
In BaseActivity you are using base menu config main.xml.
public class BaseActivity extends SherlockFragmentActivity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
In child activity you are using another config from home.xml only with additional menu items, no duplicates. But don't forget to call super.onCreateOptionsMenu(menu) with the same menu instance to add elements from BaseActivity (parent menu items would be added after child menu items if you call super's method after inflate, and before otherwise).
public class HomeActivity extends BaseActivity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.home, menu);
return super.onCreateOptionsMenu(menu);
}
}
You can specify your actions for the actionbar in the main.xml
example :
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"/>
<item android:id="#+id/action_compose"
android:icon="#drawable/ic_action_compose"
android:title="#string/action_compose" />
And call from your subclass
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
Make different xml files containing the buttons you need specific to those Activity. Say for Activity1 you have two buttons and for Activity2 you have one, then you will create 2 xml files like below.
action_activity1.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"/>
<item android:id="#+id/action_compose"
android:icon="#drawable/ic_action_compose"
android:title="#string/action_compose" />
</menu>
action_activity2.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"/>
</menu>
Then in the onCreateOptionsMenu(Menu menu) method inflate the desired xml file. Like,
Activity1:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.action_activity1, menu);
return true;
}
Activity2:
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.action_activity2, menu);
return true;
}
Please be care full with the syntax (as I used appcompat actionbar). :)
This is what I use. Hope you find it helpful. And, I will be happy to see an easier way than this. :)
Related
I tried
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.v(
this.getClass().getName() + "!!!",
new Exception().getStackTrace()[0].getMethodName()
);
MenuItem m_item = (MenuItem)menu.findItem(R.id.action_settings);
if(m_item != null)
m_item.setTitle("Back to test");
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.settings, menu);
return true;
}
but it always gets null.And also,onCreate seems to have it as null as well. Is there a function that i can modify the text on it during runtime??? And if so, is there an easy way to find it?
You should add items in the menu xml. You can find it on the folder res/menu. There you have all the menus available for inflation.
I suppose that you have only one. This is how it could look with added options:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="#+id/searchMain"
android:icon="#drawable/ic_action_search"
app:showAsAction="ifRoom|withText"
android:title="Search"/>
<item
android:id="#+id/searchBarcodeScan"
android:icon="#drawable/ic_launcher"
app:showAsAction="always|withText"
android:title="Scanner"/>
<item
android:id="#+id/seeList"
android:icon="#drawable/ic_launcher"
app:showAsAction="ifRoom|withText"
android:title="See list"/>
<item
android:id="#+id/settings"
android:icon="#drawable/ic_settings"
app:showAsAction="ifRoom|withText"
android:title="Settings"/>
</menu>
Then in your activity you can react to the option selected by overriding this method and doing things inside it:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.searchMain:
doSomething();
return true;
case R.id.searchBarcodeScan:
doSomething2();
return true;
case R.id.seeList:
doSomething3();
return true;
case R.id.settings:
doSomething4();
return true;
}
return super.onOptionsItemSelected(item);
}
EDIT
In order to change menus in runtime, you should call the method invalidateOptionsMenu(). This method will force the recreation of the menu and this time onPrepareOptionsMenu method will be called. You should override it in your Activity this way:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(someCondition){
getMenuInflater().inflate(R.menu.main_menu, menu);
}
else if(someOtherCondition){
getMenuInflater().inflate(R.menu.other_menu, menu);
}
return true;
}
Instead of
getMenuInflater().inflate(R.menu.settings, menu);
do something like:
getMenuInflater().inflate(R.menu.menu_custom, menu);
where res/menu/menu_custom.xml is something like:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/menu_search"
android:icon="#drawable/ic_action_search"
android:title="#string/search"/>
<item android:id="#+id/menu_settings"
android:icon="#drawable/ic_action_settings"
android:title="#string/settings" />
</menu>
This will give you two items in the dropdown. It looks like your res/menu/settings.xml only has one item in it.
For some reason, I cannot get my button to appear on the Action Bar. I have defined it in an XML file in /res/menu, along with inflating it and listening for an action. The icon is present in /res/drawable-hdpi. And nothing of interest shows in logcat. :(
XML:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/logout"
android:icon="#drawable/logout"
android:title="Logout"
android:orderInCategory="100"
android:showAsAction="always" />
</menu>
Code in main activity:
public class MainActivity extends ActionBarActivity {
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.logout:
//logout code
return true;
default:
return super.onOptionsItemSelected(item);
}
}
//rest of app
}
I followed this question for my initial problem, and it didn't help. How to add button in ActionBar(Android)?
Try with this change:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/logout"
android:icon="#drawable/logout"
android:title="Logout"
android:orderInCategory="100"
yourapp:showAsAction="always" />
</menu>
I want to add an action to the action bar, but it appears in my action bar as a drop down list.
How can I add button to the action bar?
My code is:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="Add"
showAsAction="ifRoom"/>
</menu>
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
If you are using android.app.Activity simply change showAsAction="always" to "android:showAsAction="always".
If you are using android.support.v7.app.Activity change the code as follows:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="Add"
app:showAsAction="ifRoom"/>
</menu>
You just simply add the one more item into menu and inflate that menu into your activity ....
like below you will add your button and access that button into your activity...
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/refresh"
android:icon="#android:drawable/stat_notify_sync"
showAsAction="ifRoom"/>
<item
android:id="#+id/action_bar_button_cancel"
android:focusableInTouchMode="true"
android:icon="#android:drawable/ic_menu_close_clear_cancel"
showAsAction="ifRoom"/>
</menu>
Inflating the menu like below.....
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
Accessing method in action bar item is....
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.refresh:
//logic
return true;
case R.id.action_bar_button_cancel:
//logic
return true;
default:
return super.onOptionsItemSelected(item);
}
}
that's if you have any doubt comment
I have a class BaseFragment i was create a private menu and set that menu from
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
this.menu = menu;
}
in main.xml i have :
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Search / will display always -->
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
android:showAsAction="ifRoom"/>
<!-- Refresh -->
<item android:id="#+id/action_refresh"
android:icon="#drawable/ic_action_refresh"
android:title="#string/action_refresh"
android:showAsAction="ifRoom" />
<!-- Download -->
<item android:id="#+id/action_download"
android:icon="#drawable/ic_action_download"
android:title="#string/action_download"
android:showAsAction="never"/>
<!-- Favorite -->
<item android:id="#+id/action_favorites"
android:icon="#drawable/ic_action_favorites"
android:title="#string/action_favorites"
android:showAsAction="never" />
</menu>
and i have another fragments FragmentA and FragmentB extends to that BaseFragment.
In FragmentA i want to show All menu and all is OK when running the app, but in FragmentB i want to show the download and and favorite whitout search and refresh.
I was try to create a method on base to manipulate the visibility on menuitem and my menu always return null.
protected void setSearchable(boolean isSearchable){
menu.findItem(R.id.action_search).setVisible(isSearchable);
}
protected void setHasRefreshFuction(boolean isHasRefreshFunction){
menu.findItem(R.id.action_refresh).setVisible(isHasRefreshFunction);
}
protected void setDownloadable(boolean isDownloadable){
menu.findItem(R.id.action_download).setVisible(isDownloadable);
}
protected void setFavorite(boolean isFavorite){
menu.findItem(R.id.action_favorites).setVisible(isFavorite);
}
i call that method on onCreate() in FragmentB like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setDownloadable(true);
setFavorite(true);
setHasRefreshFuction(false);
setSearchable(false);
}
Can someone help me please.... i was read many tutorial and doesn't find an answer to make this.
note : I was setHasOptionsMenu(true); in oncreate in BaseFragment
The easiest way would be to override onCreateOptionsMenu in FragmentB again.
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
menu.findItem(R.id.action_search).setVisible(false);
menu.findItem(R.id.action_refresh).setVisible(false);
this.menu = menu;
}
You can't access menu outside it's callbacks. For you can implement ActionProvider subclass to handle visibility of needed menu items.
Or you can call invalidateOptionsMenu() method of your activity to request Options Menu recreating, and change visibility of items in onCreateOptionsMenu()
In the menu.xml you should add all the menu items. Then you can hide items that you don't want to see in the initial loading.
<item
android:id="#+id/action_newItem"
android:icon="#drawable/action_newItem"
android:showAsAction="never"
android:visible="false"
android:title="#string/action_newItem"/>
Add setHasOptionsMenu(true) in the onCreate() method to invoke the menu items in your Fragment class.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
You don't need to override onCreateOptionsMenu in your Fragment class again. Menu items can be changed (Add/remoev) by overriding onPrepareOptionsMenumethod available in Fragment.
#Override
public void onPrepareOptionsMenu(Menu menu) {
menu.findItem(R.id.action_newItem).setVisible(true);
super.onPrepareOptionsMenu(menu);
}
I have an activity that extends the ActionBarActivity that's included in the support package revision 18. I have a menu item that contains a submenu and it works fine when I load up the app. However, if I call supportInvalidateOptionsMenu() for some reason the submenu doesn't pop up any more. The related code would be the xml for the menu
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:myapp="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/menu_search"
android:icon="#drawable/ic_search"
android:title="#string/menu_search"
myapp:actionViewClass="android.support.v7.widget.SearchView"
myapp:showAsAction="always|collapseActionView"/>
<item
android:id="#+id/menu_now_playing"
android:icon="#drawable/ic_nowplaying"
android:title="#string/menu_nowplaying"
myapp:showAsAction="always"/>
<item
android:id="#+id/menu_station_overflow"
android:icon="#drawable/ic_overflow"
android:title="#string/more"
myapp:showAsAction="always">
<menu>
<item
android:id="#+id/menu_favorite"
android:icon="#drawable/ic_favorite"
android:title="#string/favorite"/>
</menu>
</item>
</menu>
And then the code to create the menu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity, menu);
return super.onCreateOptionsMenu(menu);
}
I should note that this problem occurs on Gingerbread devices but there are no problems on android 4.x. Does anyone have any idea what might be going on here?
Here is a work-around (as we had the same issue). Any menu items that need to be modified later, we put into instance variables, example:
private MenuItem stationMenuItem;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity, menu);
stationMenuItem = menu.findItem(R.id.menu_station_overflow);
return super.onCreateOptionsMenu(menu);
}
public void doStuff(boolean menuVisible) {
if (stationMenuItem != null) {
stationMenuItem.setVisible(menuVisible);
}
}
This is NOT an ideal solution, but something that will work till this is fixed. Changes to menu items SHOULD happen in onPrepareOptionsMenu(Menu menu) after calling supportInvalidateOptionsMenu()
Do not return super.onCreateOptionsMenu(menu); because that will always return false. Just return true.