Is there any easy way of adding a simple badge/dot on the Overflow Menu (three-dot menu) icon on the Toolbar?
I'm trying to show the user that there is a new menu item inside. Note that I should be able to add/remove this programmatically. Any help is appreciated.
First, customize the overflow button style in styles.xml:
<!-- Application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<!-- Your theme customization... -->
<item name="android:actionOverflowButtonStyle">#style/MyActionOverflowButtonStyle</item>
</style>
<!-- Here you choose the ID of the overflow icon. -->
<item type="id" name="myActionOverflowButtonID"/>
<!-- Style to replace action bar overflow icon. -->
<style name="MyActionOverflowButtonStyle" parent="Widget.AppCompat.ActionButton.Overflow">
<item name="android:id">#id/myActionOverflowButtonID</item>
</style>
(inspired by How to change three dots button on android to other button, but with android:id instead of android:src in the style)
Then, add a badge:
// Get the button view
val view = findViewById<View>(R.id.myActionOverflowButtonID)
// Create and customize a badge, e.g:
val badgeDrawable = BadgeDrawable.create(context).apply {
backgroundColor = getColor(R.color.primary)
horizontalOffset = 30
verticalOffset = 30
number = 2
}
// Attach the badge to the button
// For this API, you need to update Material components dependency to 1.3.0 or later
BadgeUtils.attachBadgeDrawable(badgeDrawable, view)
You can use simple BadgeDrawable:
val badgeDrawable = BadgeDrawable.create(context).apply {
// configure (set background color, offsets, etc)
}
and add/remove it later:
BadgeUtils.attachBadgeDrawable(badgeDrawable, toolbar, menuItemId)
or
BadgeUtils.detachBadgeDrawable(badgeDrawable, toolbar, menuItemId)
Related
I'm using default PopupMenu. I've customized it in my XML style, and now it has a dark style. but I have a problem now: please look at this screenShot I've prepared:
As you can see the arrow is kind of hard to see and I really wish to avoid using popup window now. Is there any way that I could change it to a white arrow?
It's been a long time, but in case anyone else runs into this problem, you can leverage a style to fix this.
it looks like the color of the arrow is controlled by android:textColorSecondary, so if you are programmatically generating a popup menu, you could do something like this (in Kotlin):
val contextThemeWrapper = ContextThemeWrapper(context, R.style.PopupMenuStyle)
val popupMenu = PopupMenu(contextThemeWrapper, view)
val menu = popupMenu.menu
menu.addSubMenu(groupId, itemId, order, groupTitle)
menu.add(groupId, itemId, order, title1)
menu.add(groupId, itemId, order, title2)
etc...
and define your PopupMenuStyle like this in your styles.xml:
<style name="PopupMenuStyle" parent="#style/<some.parent.style>">
<!--this makes an the arrow for a menu's submenu white-->
<item name="android:textColorSecondary">#android:color/white</item>
</style>
custom theme and set listMenuViewStyle
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<item name="listMenuViewStyle">#style/listMenuViewStyle</item>
</style>
set subMenuArrow
<style name="listMenuViewStyle" parent="Base.Widget.AppCompat.ListMenuView">
<item name="subMenuArrow">#drawable/icon_sub_menu</item>
</style>
apply custom theme to activity
<activity android:name=".material.MyTopAppBarActivity"
android:theme="#style/AppTheme"/>
I am trying to customize background and color of Title bar. I have seen many example on android site and stack overflow but nothing worked out for me.
In examples they are adding new elements in title bar but i want to customize existing title bar.
I do not want to change anything else. I only want to change background color and font color of text.
If you are using Android Lollipop (api 21+), you can edit the "styles21.xml" (in the res directory) code and add the following:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Material">
<!-- Customize your theme using Material Design here. -->
<!-- Title Bar color here -->
<item name="android:colorPrimary">#YOUR_COLOR_HERE</item>
<!-- Background color here -->
<item name="android:windowBackground">#YOUR_COLOR_HERE</item>
</style>
</resources>
For more information see Google's "Using the Material Theme" here.
This XML code will work throughout the whole app (each different view) unless otherwise specified.
I hope this is what you are looking for!
I'm having issues creating a Material Design app with the AppCompat v21 theme. First I have my app theme using the AppCompat light with dark actionbar.
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="colorPrimary">#color/theme_color</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">#color/theme_color_dark</item>
<!-- theme UI controls like checkboxes and text fields -->
<item name="colorAccent">#color/theme_color_accent</item>
</style>
The color branding for my app is quite dark which is why I use the DarkActionBar variant. My problem is that I have a couple layouts where I'd like to put a Spinner and an EditText inside a layout where the background is my theme_color which is dark. This results in a Spinner/EditText with black color on a dark background. How can I make the style/theme of these controls use the Dark variant so they show up with white text instead of black text. Even worse than that, I need the spinner to show white text but dropdown items of the spinner to show the light version.
I'm using a Spinner inside a Toolbar with dark background and remembered that the Google I/O Android App does the same, so I looked at its styles - more specifically, the ActionBarThemeOverlay here.
After I used the below attributes on my theme, my Spinner background color (the "arrow") changed:
<item name="colorControlNormal">#fff</item>
<item name="colorControlHighlight">#3fff</item>
colorControlHighlight is the color when the user presses the Spinner. I didn't test on an EditText, though.
So, you're looking for a way to apply a different theme to select views.
There's no xml-only way to do that for most elements (except Toolbar, which you already know)
You'll have to inflate the views manually, using a ContextThemeWrapper:
ContextThemeWrapper wrapper = new ContextThemeWrapper(getActivity(),
R.style.Theme_AppCompat); // The dark one
LayoutInflater footPump = LayoutInflater.from(getActivity()).cloneInContext(wrapper);
// Note null as second argument -- if you pass in parent view, theme will
// be taken from the parent
Spinner spinner = (Spinner) footPump.inflate(R.layout.spinner, null);
to have the layout resource for the inflater, just create a single-view xml file:
<!-- res/layout/spinner.xml -->
<?xml version="1.0" encoding="utf-8"?>
<Spinner xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
How about this..
make a style for you widget, ex:
<style name="CustomEditText" parent="android:Widget.EditText">
<item name="android:textColor">#color/red</item>
</style>
then in your xml add this attribute to your EditText
style="#style/CustomEditText"
In one of my Activities, I changed the Toolbar color using Palette. But on 5.0 devices using ActionBarActivity the status bar color is the color of my colorPrimaryDark in my activity theme so I have 2 very different colors and it does not look good.
I realize that in 5.0 you can use Window.setStatusBarColor() but ActionBarActivity does not have this.
so my question is in 5.0 how can I change the status bar color with ActionBarActivity?
I'm not sure I understand the problem.
I you want to change the status bar color programmatically (and provided the device has Android 5.0) then you can use Window.setStatusBarColor(). It shouldn't make a difference whether the activity is derived from Activity or ActionBarActivity.
Just try doing:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(Color.BLUE);
}
Just tested this with ActionBarActivity and it works alright.
Note: Setting the FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag programmatically is not necessary if your values-v21 styles file has it set already, via:
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
There are various ways of changing the status bar color.
Using the styles.xml. You can use the android:statusBarColor attribute to do this the easy but static way.
Note: You can also use this attribute with the Material theme.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
</resources>
You can get it done dynamically using the setStatusBarColor(int) method in the Window class. But remember that this method is only available for API 21 or higher. So be sure to check that, or your app will surely crash in lower devices.
Here is a working example of this method.
if (Build.VERSION.SDK_INT >= 21) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(getResources().getColor(R.color.primaryDark));
}
where primaryDark is the 700 tint of the primary color I am using in my app. You can define this color in the colors.xml file.
I don't think the status bar color has been implemented in AppCompat yet. These are the attributes which are available:
<!-- ============= -->
<!-- Color palette -->
<!-- ============= -->
<!-- The primary branding color for the app. By default, this is the color applied to the
action bar background. -->
<attr name="colorPrimary" format="color" />
<!-- Dark variant of the primary branding color. By default, this is the color applied to
the status bar (via statusBarColor) and navigation bar (via navigationBarColor). -->
<attr name="colorPrimaryDark" format="color" />
<!-- Bright complement to the primary branding color. By default, this is the color applied
to framework controls (via colorControlActivated). -->
<attr name="colorAccent" format="color" />
<!-- The color applied to framework controls in their normal state. -->
<attr name="colorControlNormal" format="color" />
<!-- The color applied to framework controls in their activated (ex. checked) state. -->
<attr name="colorControlActivated" format="color" />
<!-- The color applied to framework control highlights (ex. ripples, list selectors). -->
<attr name="colorControlHighlight" format="color" />
<!-- The color applied to framework buttons in their normal state. -->
<attr name="colorButtonNormal" format="color" />
<!-- The color applied to framework switch thumbs in their normal state. -->
<attr name="colorSwitchThumbNormal" format="color" />
(From \sdk\extras\android\support\v7\appcompat\res\values\attrs.xml)
Just paste this function in your Utils class where you keep your all other common functions.
fun Activity.changeStatusBarColor(color: Int, isLight: Boolean) {
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.statusBarColor = color
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = isLight
}
and use it from anywhere like this:
changeStatusBarColor(
ContextCompat.getColor(
context,
R.color.black
), false
)
Note that here I also have managed the dark and light status bar colors separately to manage out icon and text colors of status bar.
Try this,
I used this and it works very good with v21.
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="colorPrimaryDark">#color/blue</item>
</style>
[Kotlin version] I created this extension that also checks if the desired color has enough contrast to hide the System UI, like Battery Status Icon, Clock, etc, so we set the System UI white or black according to this.
fun Activity.coloredStatusBarMode(#ColorInt color: Int = Color.WHITE, lightSystemUI: Boolean? = null) {
var flags: Int = window.decorView.systemUiVisibility // get current flags
var systemLightUIFlag = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
var setSystemUILight = lightSystemUI
if (setSystemUILight == null) {
// Automatically check if the desired status bar is dark or light
setSystemUILight = ColorUtils.calculateLuminance(color) < 0.5
}
flags = if (setSystemUILight) {
// Set System UI Light (Battery Status Icon, Clock, etc)
removeFlag(flags, systemLightUIFlag)
} else {
// Set System UI Dark (Battery Status Icon, Clock, etc)
addFlag(flags, systemLightUIFlag)
}
window.decorView.systemUiVisibility = flags
window.statusBarColor = color
}
private fun containsFlag(flags: Int, flagToCheck: Int) = (flags and flagToCheck) != 0
private fun addFlag(flags: Int, flagToAdd: Int): Int {
return if (!containsFlag(flags, flagToAdd)) {
flags or flagToAdd
} else {
flags
}
}
private fun removeFlag(flags: Int, flagToRemove: Int): Int {
return if (containsFlag(flags, flagToRemove)) {
flags and flagToRemove.inv()
} else {
flags
}
}
Thanks for above answers, with the help of those, after certain R&D for xamarin.android MVVMCross application, below worked
Flag specified for activity in method OnCreate
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
this.Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
}
For each MvxActivity, Theme is mentioned as below
[Activity(
LaunchMode = LaunchMode.SingleTop,
ScreenOrientation = ScreenOrientation.Portrait,
Theme = "#style/Theme.Splash",
Name = "MyView"
)]
My SplashStyle.xml looks like as below
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Splash" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:statusBarColor">#color/app_red</item>
<item name="android:colorPrimaryDark">#color/app_red</item>
</style>
</resources>
And I have V7 appcompact referred.
Applying
<item name="android:statusBarColor">#color/color_primary_dark</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
in Theme.AppCompat.Light.DarkActionBar didn't worked for me. What did the trick is , giving colorPrimaryDark as usual along with android:colorPrimary in styles.xml
<item name="android:colorAccent">#color/color_primary</item>
<item name="android:colorPrimary">#color/color_primary</item>
<item name="android:colorPrimaryDark">#color/color_primary_dark</item>
and in setting
if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
Window window = this.Window;
Window.AddFlags(WindowManagerFlags.DrawsSystemBarBackgrounds);
}
didn't had to set statusbar color in code .
This can be implemented if you're using Kotliln in Android:
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.statusBarColor = Color.WHITE
add this kotlin code in OnCreate() of Activity or Fragment :
if (Build.VERSION.SDK_INT >= 21) {
val window: Window = requireActivity().window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.statusBarColor = resources.getColor(R.color.very_light_pink)
}
I'm looking for style information on the Contextual Action bar (CAB). I just need to change the colour of the text in fact..
As you can see from the above, this is using the standard Theme.Holo.Light.DarkActionBar theme, so I just need to set the text colour to white!
Can anyone point me in the right direction?
To change the color/etc of the text in a contextual action bar:
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//mode.setTitle("Contextual Action Bar"); (replace this call)
TextView tv= (TextView)getLayoutInflater().inflate(R.layout.contextual_title, null);
tv.setText("Contextual Action Bar");
mode.setCustomView(tv);
where layout/contextual_title.xml contains a single TextView with your desired color/size/style etc
In fact, almost everything in a contextual action bar can be styled. The only problem is that searching for the word 'contextual' leads nowhere useful. The relevant styling features are all called "actionMode...". Here are some I used (defined in my Theme.)
<item name="android:actionModeCloseDrawable">#drawable/check</item>
<item name="android:actionModeCutDrawable">#drawable/ic_menu_cut_holo_dark</item>
<item name="android:actionModeCopyDrawable">#drawable/ic_menu_copy_holo_dark</item>
<item name="android:actionModePasteDrawable">#drawable/ic_menu_paste_holo_dark</item>
<item name="android:actionModeSelectAllDrawable">#drawable/ic_menu_selectall_holo_dark</item>
<item name="android:actionModeBackground">#drawable/contextual</item>
<item name="android:actionModeCloseButtonStyle">#style/MyCloseButton</item>
<!-- these change the press backgrounds for the vanilla actionBar and for search -->
<item name="android:windowContentOverlay">#null</item>
<item name="android:selectableItemBackground">#drawable/bar_selector</item>
<item name="android:actionBarItemBackground">#drawable/bar_selector</item>
<!-- these were defined in platform/.../data/res/values/... but Eclipse didn't recognize them -->
<!--? item name="android:actionModeShareDrawable">#drawable/icon</item -->
<!--? item name="android:actionModeFindDrawable">#drawable/icon</item -->
<!--? item name="android:actionModeWebSearchDrawable">#drawable/icon</item -->
<!-- item name="android:actionModeBackground">#drawable/red</item -->
<!-- and finally -->
<style name="MyCloseButton" parent="android:style/Widget.ActionButton.CloseMode">
<item name="android:background">#drawable/bar_selector</item>
</style>
You can easily set your own text-editing cut/paste/copy/selectall icons, the bar
background, and the icon background that changes color when you press the icons(bar_selector above). The icons are ImageViews, not buttons, and the edit id's (and the pressable background) are attached to the ImageView's parent (one parent per view) which is an 'internal' type.
It's never clear what goes where in the styles--I found where selectableItemBackground was in the platform Themes.xml, and copied and modified the drawable pointed at.
I posted a comment to my own question, and this is actually a bug in the version of android I was using (Probably an early version of 4.0)
This is the bug described: http://code.google.com/p/android/issues/detail?id=26008
If you're starting the contextual action mode manually, you can call setTheme() with a new theme before launching it (maybe Theme.AppCompat.Light.DarkActionBar if you're trying to avoid the black-on-black text issue). This will not affect the theme of the current activity if you've already set the activity's content view.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
// these lines can occur anywhere so long as you've already
// called "setContentView()" on the activity. The theme
// you set here will apply to the action mode, but not to
// the activity.
setTheme(R.style.Theme_AppCompat_Light_DarkActionBar);
startSupportActionMode(myActionModeCallback);
}
it works now, but you have to enter it in values/styles.xml (not values-v#/styles.xml) and enter it in the general (non-API specific tag)
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:actionModeCloseDrawable">#drawable/ic_launcher</item>
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>