I have three menu items in my app and i want to change the background image , text color and font for all items but nothing getting changed.
This is the following code.
Java Code -:
public boolean onCreateOptionsMenu(android.view.Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.custom_menu, menu);
getLayoutInflater().setFactory(new Factory()
{
public View onCreateView(String name, final Context context,
AttributeSet attrs)
{
if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView"))
{
try
{
LayoutInflater li = LayoutInflater.from(context);
final View view = li.createView(name, null, attrs);
new Handler().post(new Runnable()
{
public void run()
{
((TextView) view).setTextSize(30);
Typeface face = Typeface.createFromAsset(getAssets(),"fonts/arialbd.ttf");
((TextView) view).setTypeface(face);
((TextView) view).setBackgroundResource(R.drawable.white6);
((TextView) view).setTextColor(Color.BLUE);
}
});
return view;
}
catch (InflateException e)
{
}
catch (ClassNotFoundException e)
{
}
}
return null;
}
});
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.abc:
break;
case R.id.xyz:
break;
case R.id.exit:
break;
}
return false;
}
XML Menu Code-:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/abc"
android:orderInCategory="10"
android:showAsAction="always"
android:title="ABC"/>
<item
android:id="#+id/xyz"
android:orderInCategory="10"
android:showAsAction="always"
android:title="XYZ"/>
<item
android:id="#+id/exit"
android:orderInCategory="10"
android:showAsAction="always"
android:title="Andi"/>
</menu>
and i want to keep all the android:showAsAction="always" , please let me know , what is the problem? Suggest me some good solution.
as i see you want to create and options menu that is doing some changes on your text, color, bg image etc.. when you click on and menu option right ?.
First of all why do u have two onCreateOptionsMenu functions, is the first one in super class or so in an activity extended class how canu extend it too. İ think u can do it in simpley way.
Create your menu items and put your #Override (d) onCreateOptionsMenu function in your class and call a different method which are doing different jobs e.g changeColor() for abc, changeThem() for xyz, changeBGImage() for qwe and so on...
and let me give u some links that are doing this way and i
http://www.mustafasevgi.com/2012/08/android-de-optionsmenu-olusturma.html
http://www.thegeekstuff.com/2013/12/android-app-menus/ (this site has more)
just check these sites if you have time..
You can see they are calling methods in the options switch case blocks for each action.
btw iam not and android developer but curiosity.
hope helps
regards.
Related
I want to change the 'font style` my menu items.
by default it's looks like this
but I want to change into this
You can customize the option menu, including:
1.Add a custom font
2.Change font size
3.Change font color
4.Set background to a Drawable resource (e.g. image, border, gradient)
To change background to a border or gradient you have to create a resource folder in res called drawable and, inside it, create the border XML or gradient XML.
This can all be done programatically as shown below:
public class CustomMenu extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public boolean onCreateOptionsMenu(android.view.Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cool_menu, menu);
getLayoutInflater().setFactory(new Factory() {
public View onCreateView(String name, Context context,
AttributeSet attrs) {
if (name.equalsIgnoreCase(
"com.android.internal.view.menu.IconMenuItemView")) {
try {
LayoutInflater li = LayoutInflater.from(context);
final View view = li.createView(name, null, attrs);
new Handler().post(new Runnable() {
public void run() {
// set the background drawable if you want that
//or keep it default -- either an image, border
//gradient, drawable, etc.
view.setBackgroundResource(R.drawable.myimage);
((TextView) view).setTextSize(20);
// set the text color
Typeface face = Typeface.createFromAsset(
getAssets(),"OldeEnglish.ttf");
((TextView) view).setTypeface(face);
((TextView) view).setTextColor(Color.RED);
}
});
return view;
} catch (InflateException e) {
//Handle any inflation exception here
} catch (ClassNotFoundException e) {
//Handle any ClassNotFoundException here
}
}
return null;
}
});
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.AboutUs:
Intent i = new Intent("com.test.demo.ABOUT");
startActivity(i);
break;
case R.id.preferences:
Intent p = new Intent("com.test.demo.PREFS");
startActivity(p);
break;
case R.id.exit:
finish();
break;
}
return false;
}
}
Dont forget to create folder called menu in res folder, and inside the menu folder create an XML for your menu (e.g. cool_menu.xml) such as this:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="about"android:id="#+id/AboutUs" />
<item android:title="Prefs" android:id="#+id/preferences" />
<item android:title="Exit" android:id="#+id/exit" />
</menu>
OR
First download the .ttf file of the font you need (arial.ttf). Place it in the assets folder(Inside assets folder create new folder named fonts and place it inside it). If txtyour is the textviews you want to apply the font , use the following piece of code,
Typeface type = Typeface.createFromAsset(getAssets(),"fonts/Kokila.ttf");
txtyour.setTypeface(type);
I'm trying to change the text color of menu item in options menu.
i read here many similar question and answers saying it's impossible via theme and style and only via code. i also tried the code example and it didn't work.
I manage to change the background using these theme attributes:
#drawable/menu_hardkey_panel_holo_dark
#drawable/menu_hardkey_panel_holo_dark
#ffffff
#ffffff
but i can't make the text color to change.
i saw an answer suggesting using android:itemTextAppearance but it didn't work as well.
I'm using Android 4.0 SDK.
any help will be highly appreciated.
Thanks,
Gidi
You can not change this it comes by default in android API. If you make changes then it is not work for different version of android device.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
getLayoutInflater().setFactory(new Factory() {
#Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
if (name .equalsIgnoreCase(“com.android.internal.view.menu.IconMenuItemView”)) {
try{
LayoutInflater f = getLayoutInflater();
final View view = f.createView(name, null, attrs);
new Handler().post(new Runnable() {
public void run() {
// set the background drawable
view .setBackgroundResource(R.drawable.my_ac_menu_background);
// set the text color
((TextView) view).setTextColor(Color.WHITE);
}
});
return view;
} catch (InflateException e) {
} catch (ClassNotFoundException e) {}
}
return null;
}
});
return super.onCreateOptionsMenu(menu);
}
I'm using Kotlin and the new Navigation component and I was able to change this by adding this line to my theme:
<item name="android:actionMenuTextColor">#color/white</item>
And then manually updating the theme applied to my toolbar like this:
toolbar = findViewById(R.id.toolbar)
toolbar.popupTheme = R.style.AppTheme
Here's the difference:
I want to have similar menu item functionality as in the chrome browser for mobile as it is in the picture. I want to have back, forward, refresh menu items in a single row. How can I implement a similar menu item? is there any reference or is there is any hack to bring this functionality?
My app is aimed only for tablets. Here is my current Action bar menu item:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/favorite"
android:showAsAction="always"
android:title="Happy"/>
<item
android:id="#+id/share_button"
android:icon="#drawable/share"
android:showAsAction="always"
android:title="Share"/>
<item
android:id="#+id/hola_button"
android:showAsAction="always"
android:title="Hola"/>
<item
android:icon="#drawable/more_actions"
android:showAsAction="always">
<menu>
<item
android:id="#+id/back_button"
android:icon="#drawable/back"
android:title="back"/>
<item
android:id="#+id/forward_button"
android:icon="#drawable/forward"
android:title="forward"/>
<item
android:id="#+id/refresh_button"
android:icon="#drawable/refresh"
android:title="refresh"/>
</menu>
</item>
</menu>
This looks like a customized Dialog with a listview and a custom listheader
OR
a listview below a simple layout with 3 buttons on top within a dialog.
You could show the same on the actionbar menu item click.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getSupportMenuInflater().inflate(R.menu.menu_items, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.show_dlg:
// Show your custom dialog
break;
}
return super.onOptionsItemSelected(item);
}
Also this tutorial would help as a reference for inflating custom menus
http://www.codeproject.com/Articles/173121/Android-Menus-My-Way
EDIT:
This examples is as an OverflowMenu (since ABS ditched the overflow-theme). you can inflate any kind of layout-combinations. This class extends from PopUpWindow and doesn't use the typical onCreateOptions. It uses the ABS-CustomView and a PopUpWindow to create menu's.
From android reference: A popup window that can be used to display an arbitrary view. The popup window is a floating container that appears on top of the current activity.
The layout looks similar to your requested layout. This view is anchored to the ActionBar but you can display it anywhere you want. Popup window supports many show functions out of the box.
Customizable OverflowMenu
public class OverflowMenu extends PopupWindow {
private View mContentView;
public OverflowMenu(Context context, int resourceId) {
super(context);
mContentView = LayoutInflater.from(context).inflate(resourceId, null);
setContentView(mContentView);
setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
// Handle touchevents
setOutsideTouchable(true);
setFocusable(true);
setBackgroundDrawable(new BitmapDrawable());
}
/**
* Attach the OverflowMenu View to the ActionBar's Right corner
* #param actionBarView
*/
public void show(View actionBarView) {
int x = actionBarView.getMeasuredWidth() - mContentView.getMeasuredWidth();
showAsDropDown(actionBarView, x, 0);
}
/**
* Return mContentView,
* used for mContentView.findViewById();
* #return
*/
public View getView(){
return mContentView;
}
}
MainActivity
public class MainActivity extends SherlockActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mai n);
final ActionBar actionBar = getSupportActionBar();
actionBar.setCustomView(R.layout.actionbar);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
final OverflowMenu menu = new OverflowMenu(this,R.layout.menu_overflow);
final ImageButton overflowBtn = (ImageButton) actionBar.getCustomView().findViewById(R.id.actionbar_overflow);
overflowBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
menu.show(actionBar.getCustomView());
}
});
}
}
You could add the menu item to the page with something like this :
OptionCommand command = new OptionCommand();
command.setActionView(view);
command.setIcon(canvas.getContext().getResources().getDrawable(android.R.drawable.ic_menu_search));
command.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
canvas.getActivity().getOptionCommands().add(command);
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
return true;
case R.id.searchIcon:
return true;
case R.id.startRefresh:
refreshItem = item;
refresh();
return true;
case R.id.stopRefresh:
if (refreshItem != null && refreshItem.getActionView() != null) {
refreshItem.getActionView().clearAnimation();
refreshItem.setActionView(null);
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void refresh() {
if (FeedActivity.this != null) {
/*
* Attach a rotating ImageView to the refresh item as an ActionView
*/
LayoutInflater inflater = (LayoutInflater) FeedActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView iv = (ImageView) inflater.inflate(
R.layout.refresh_action_view, null);
Animation rotation = AnimationUtils.loadAnimation(
FeedActivity.this, R.anim.clockwise_refresh);
rotation.setRepeatCount(Animation.INFINITE);
iv.startAnimation(rotation);
refreshItem.setActionView(iv);
}
}
Before Clicking:
After Clicking:
Here the icon is being animated(rotating).
Problem:
why is it shifting to the left?
once it shifts to the left, the icon becomes non clickable and strangely the device back button also doesn't work
EDIT:
In comments below this answer:
Animated Icon for ActionItem
Jake Warton says if you are using a square and correct sized icon for the menu item, you wont get this weird behaviour, to someone who has the same problem.
But i am using a 32x32 image on a device which uses mdpi drawables. Which as stated there must work :(
Thank You
EDIT:
refresh_action_view.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/Widget.Sherlock.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_refresh" />
Custom Style i use in my app
<style name="My_solid_ActionBar" parent="#style/Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="background">#drawable/ab_solid_My</item>
<item name="backgroundStacked">#drawable/ab_stacked_solid_My</item>
<item name="backgroundSplit">#drawable/ab_bottom_solid_My</item>
<item name="progressBarStyle">#style/My_ProgressBar</item>
<item name="android:background">#drawable/ab_solid_My</item>
<item name="android:backgroundStacked">#drawable/ab_stacked_solid_My</item>
<item name="android:backgroundSplit">#drawable/ab_bottom_solid_My</item>
<item name="android:progressBarStyle">#style/My_ProgressBar</item>
</style>
The issue is that you're not handling all menu inflation in onCreateOptionsMenu(). The basic logic for an ActionBar refresh animation I've seen used in apps with open source , for example Andlytics (and also used myself in projects), is to implement a boolean flag in onCreateOptionsMenu() to decide whether to show the refresh animation.
You can implement it like this: When your refresh() method is called, it sets the boolean isRefreshing flag to true and calls inValidateOptionsMenu() which 'behind the scene' calls onCreateOptionsMenu() to start the animation:
Inflate the menu in onCreateOptionsMenu(...):
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
super.onCreateOptionsMenu(menu, inflater);
//inflate a menu which shows the non-animated refresh icon
inflater.inflate(R.menu.my_ab_menu, menu);
if (isRefreshing) {
//if we're refreshing, show the animation
MenuItem item = menu.findItem(R.id.refreshMenuItem);
item.setActionView(R.layout.action_bar_indeterminate_progress);
ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView);
((AnimationDrawable) iv.getDrawable()).start();
}
}
Start animation like so:
public void refresh(){
isRefreshing = true;
inValidateOptionsMenu();
}
If you want the user to start the animation when he taps the refresh icon, do like this in onOptionsItemSelected():
case R.id.refreshMenuItem:
isRefreshing = true;
item.setActionView(R.layout.action_bar_indeterminate_progress);
ImageView iv = (ImageView) item.getActionView().findViewById(R.id.loadingImageView);
((AnimationDrawable) iv.getDrawable()).start();
//...
To stop the animation call:
isRefreshing = false;
invalidateOptionsMenu();
This code is from a Fragment so you may have to tweak if for an Activity, but I think it communicates the basic idea.
I tried the exact same code you use and it works just fine for me. The only things that might be different are two things:
1) the refresh_action_view layout (here's mine for comparison):
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
style="?attr/actionButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_menu_refresh" />
2) The display options of your action bar (here's my styles.xml for comparison).
<resources>
<style name="AppTheme" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="android:actionBarStyle">#style/Widget.ActionBar</item>
<item name="actionBarStyle">#style/Widget.ActionBar</item>
</style>
<style name="Widget.ActionBar" parent="Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="android:displayOptions">showHome|useLogo|showCustom</item>
<item name="displayOptions">showHome|useLogo|showCustom</item>
</style>
</resources>
Can you share yours as well?
I would like to display badges on menu items. How do I do it?
Basically, I don't want to draw or use the canvas to do so.
You could try creating a LayerListDrawable, with your regular icon as the first layer and your badge as the second layer, then use that with setIcon() on MenuItem.
The options menu in Android can be customized to set the background or change the text appearance. The background and text color in the menu couldn’t be changed using themes and styles.
The Android source code (data\res\layout\icon_menu_item_layout.xml) uses a custom item of class “com.android.internal.view.menu.IconMenuItem”View for the menu layout. We can make changes in the above class to customize the menu. To achieve the same, use the LayoutInflater factory class and set the background and text color for the view.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
getLayoutInflater().setFactory(new Factory() {
#Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
if (name .equalsIgnoreCase(“com.android.internal.view.menu.IconMenuItemView”)) {
try{
LayoutInflater f = getLayoutInflater();
final View view = f.createView(name, null, attrs);
new Handler().post(new Runnable() {
public void run() {
// Set the background drawable
view .setBackgroundResource(R.drawable.my_ac_menu_background);
// Set the text color
((TextView) view).setTextColor(Color.WHITE);
}
});
return view;
}
catch (InflateException e) {
}
catch (ClassNotFoundException e) {
}
}
return null;
}
});
return super.onCreateOptionsMenu(menu);
}
Menuitem has an attribute icon, for example:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/mi_main_preferences"
android:title="#string/cmd_preferences"
android:icon="#android:drawable/ic_menu_preferences">
</item>
</menu>
Above example uses system icon (preferences menu).