Is there a way I can change all the alert dialogs appearing in my Android application? I want to change the dialogs that are system generated as well (like the Edit Text dialog that opens up when you long tap on any EditText). I want to change the title font color and size of all the dialogs in my app.
Is there a way to do it?
I have tried setting android:alertDialogTheme in my theme. But it seems to be not working. Code following -
<style name="Theme.DLight" parent="android:Theme.Light.NoTitleBar">
<item name="android:alertDialogTheme">#style/DialogStyle</item>
</style>
and
<style name="DialogStyle" parent="android:Theme" >
<item name="android:windowBackground">#drawable/background_holo_light</item>
<item name="android:textColor">#014076</item>
</style>
EDIT
I'm not invoking a dialog from my code. It's just the default dialog
that appears when you long click on any EditText. Generally it
contains the keyboard options like Select word, Select all, Input
method etc.
In you dialog theme, the attribute you need to modify windowTitleStyle. There, reference a style for your title and define a text appearance for this title. For example, to display your title red and bold:
<style name="AppTheme" parent="#android:style/Theme.Holo">
...
<item name="alertDialogTheme">#style/AppTheme.AlertDialog</item>
</style>
<style name="DialogStyle" parent="#style/Theme.Holo.Dialog.Alert">
...
<item name="android:windowTitleStyle">#style/DialogWindowTitle_Custom</item>
</style>
<style name="DialogWindowTitle_Custom" parent="#style/DialogWindowTitle_Holo">
<item name="android:maxLines">1</item>
<item name="android:scrollHorizontally">true</item>
<item name="android:textAppearance">#style/TextAppearance_DialogWindowTitle</item>
</style>
<style name="TextAppearance_DialogWindowTitle" parent="#android:style/TextAppearance.Holo.DialogWindowTitle">
<item name="android:textColor">#android:color/holo_red_light</item>
<item name="android:textStyle">bold</item>
</style>
If you want to style a little bit more your AlertDialog, I wrote a blog post detailing the steps.
In styles.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
//All your other styles and add the one mntioned below.
<item name="alertDialogTheme">#style/AlertDialogStyle</item>
</style>
In the styles of AlertDialog add:
<style name="AlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="colorAccent">#color/colorAccent</item>
<item name="android:textColorPrimary">#color/primary_text</item>
<item name="android:editTextColor">#color/primary_text</item>
<item name="android:background">#color/white</item>
<item name="android:windowTitleStyle">#style/TextAppearance.AppCompat.Title</item>
</style>
windowTitleStyle is important to add as it will give your title that effect that you need.
Now simply use this Theme in your AlertDialog in any activity that you want like below:
AlertDialog.Builder dialog = new AlertDialog.Builder(this, R.style.AlertDialogStyle);
Related
I try to use widgets from Material Components only, but in many cases, it's not documented how styling can be achieved.
Let's consider MaterialAlertDialog.
Each time I want to show a dialog, I call such part of the code:
MaterialAlertDialogBuilder(context, R.style.Theme_MyApp_Dialog_Alert)
.setTitle("Title")
.setMessage("This is message.")
.setPositiveButton(R.string.ok) { _, _ -> }
.show()
As you can see, I'm using a custom theme.
<style name="Theme.MyApp.Dialog.Alert" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<!-- attributes here -->
</style>
The problem is that some of the attributes are not working. For example textColor. So the question is how to change the body or title text color in MaterialAlertDialog?
I use the newest version of Material Components - 1.1.0-alpha07.
PS.
I'm not sure which theme should be a parent. In Material Theme Builder they use #style/ThemeOverlay.MaterialComponents.Dialog.Alert which actually gives an "old" look of dialogs.
Change the style as below
<style name="Theme.MyApp.Dialog.Alert" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="materialAlertDialogTitleTextStyle">#style/MaterialAlertDialogText</item>
</style>
Create MaterialAlertDialogText style and set textColor
<style name="MaterialAlertDialogText" parent="#style/MaterialAlertDialog.MaterialComponents.Title.Text">
<item name="android:textColor">#color/yourTextColor</item>
</style>
You can simply override the default colors using:
<style name="Theme.MyApp.Dialog.Alert" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<!-- Text Color for title and message -->
<item name="colorOnSurface">#color/....</item>
....
</style>
Otherwise you can customize the style used by the title and the body text using:
<style name="Theme.MyApp.Dialog.Alert" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<!-- Title -->
<item name="materialAlertDialogTitleTextStyle">#style/MyTitle_MaterialAlertDialog.MaterialComponents.Title.Text</item>
<!-- Body -->
<item name="materialAlertDialogBodyTextStyle">#style/BodyTextAppearance.MaterialComponents.Body2</item>
</style>
<style name="MyTitle_MaterialAlertDialog.MaterialComponents.Title.Text" parent="#style/MaterialAlertDialog.MaterialComponents.Title.Text">
<item name="android:textColor">#color/...</item>
<item name="android:textAppearance">#style/....</item>
</style>
<style name="BodyTextAppearance.MaterialComponents.Body2" parent="#style/MaterialAlertDialog.MaterialComponents.Body.Text">
<item name="android:textColor">#color/....</item>
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textAllCaps">true</item>
<item name="fontFamily">sans-serif-condensed-light</item>
</style>
Recently I switched from support library to com.google.android.material:material:1.0.0
But now I have a problem, in this pages there's a note https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md
Note: Using a Material Components theme enables a custom view inflater which replaces default components with their Material counterparts. Currently, this only replaces Button XML components with MaterialButton.
And the theme I am using
Theme.MaterialComponents.Light.NoActionBar
does exactly what it says in that note, it replaces AlertDialog Buttons to MaterialButtons but the problem is that by default MaterialButtons are colored background and now the buttons looks like this:
How can I make them borderless and backgroundless again?
PS I am using alert builder to create alert dialogs:
android.app.AlertDialog.Builder
I figured out what was causing this problem. I need to use different AlertDialog class:
androidx.appcompat.app.AlertDialog
When I switched to this everything started working as expected. Here's where I found the solution:
https://github.com/material-components/material-components-android/issues/162
When using com.google.android.material:material:1.0.0 and androidx.appcompat.app.AlertDialog you can customize each button in the buttonBar by using Widget.MaterialComponents.Button.TextButton as parent.
val builder: AlertDialog.Builder = AlertDialog.Builder(ContextThemeWrapper(context, R.style.AlertDialogTheme))
Use the default layout or add a custom by builder.setView(R.layout.my_dialog)
In your styles:
<style name="AlertDialogTheme" parent="Theme.MaterialComponents.Light.Dialog.Alert">
<item name="buttonBarPositiveButtonStyle">#style/Alert.Button.Positive</item>
<item name="buttonBarNegativeButtonStyle">#style/Alert.Button.Neutral</item>
<item name="buttonBarNeutralButtonStyle">#style/Alert.Button.Neutral</item>
</style>
<style name="Alert.Button.Positive" parent="Widget.MaterialComponents.Button.TextButton">
<item name="backgroundTint">#color/transparent</item>
<item name="rippleColor">#color/colorAccent</item>
<item name="android:textColor">#color/colorPrimary</item>
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">false</item>
</style>
<style name="Alert.Button.Neutral" parent="Widget.MaterialComponents.Button.TextButton">
<item name="backgroundTint">#color/transparent</item>
<item name="rippleColor">#color/colorAccent</item>
<item name="android:textColor">#color/gray_dark</item>
<item name="android:textSize">14sp</item>
</style>
If you are using the Material Components library the best way to have an AlertDialog is to use the MaterialAlertDialogBuilder.
new MaterialAlertDialogBuilder(context)
.setTitle("Dialog")
.setMessage("Lorem ipsum dolor ....")
.setPositiveButton("Ok", /* listener = */ null)
.setNegativeButton("Cancel", /* listener = */ null)
.show();
It is the default result:
If you want also to apply a different style or color to the buttons you can check this answer.
I tested the above answers. Although I got a good idea, none worked for my case. So, this is my answer.
Make sure to have android:theme="#style/AppMaterialTheme" in your manifest file under Application or Activity.
Open your Styles.xml file and change it based on the following.
<style name="AppMaterialTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">#color/primaryBlue</item>
<item name="colorPrimaryDark">#color/primaryBlue</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="colorControlActivated">#color/primaryBlue</item>
<item name="colorControlHighlight">#color/colorAccent_main</item>
<item name="colorButtonNormal">#color/white</item>
<item name="materialAlertDialogTheme">#style/AlertDialogMaterialTheme</item>
</style>
<style name="AlertDialogMaterialTheme" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="buttonBarPositiveButtonStyle">#style/Alert.Button.Positive</item>
<item name="buttonBarNegativeButtonStyle">#style/Alert.Button.Negative</item>
</style>
<style name="Alert.Button.Positive" parent="Widget.MaterialComponents.Button.UnelevatedButton">
<item name="android:fillColor">#color/color_0054BB</item>
<item name="android:textColor">#color/white</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="rippleColor">#color/colorAccent_main</item>
</style>
<style name="Alert.Button.Negative" parent="Widget.MaterialComponents.Button.OutlinedButton">
<item name="strokeColor">#color/color_0054BB</item>
<item name="android:textColor">#color/color_0054BB</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
<item name="android:layout_marginEnd">8dp</item>
<item name="rippleColor">#color/colorAccent_main</item>
</style>
You won't need to apply the theme to your AlertDialog as your Activity applies the theme to it. So, create the dialog normally.
The result will be.
First, it's better to use use MaterialAlertDialog if you are using Material Theme.
You can read more here – Material.io → Theming dialogs
MaterialAlertDialogBuilder(context)
.setTitle(R.string.confirm)
.setMessage(R.string.logout)
.setPositiveButton(R.string.logout_alert_positive) { _, _ -> activity?.logout() }
.setNegativeButton(R.string.never_mind, null)
.show()
This is the layout.xml of the MaterialAlertDialog actions. As you can see there are 3 buttons and each has their own styles. So, here is how you can change them.
Step 1: Tell Android that you want to alter the default MaterialAlertDialog theme.
<style name="Base.AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
...
<item name="materialAlertDialogTheme">#style/AlertDialog</item>
...
</style>
Step 2: Tell Android that you want to alter a specific button style. buttonBarNeutralButtonStyle, buttonBarNegativeButtonStyle or buttonBarPositiveButtonStyle
<style name="AlertDialog" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="buttonBarNegativeButtonStyle">#style/NegativeButtonStyle</item>
</style>
Step 3: Define your custom style
<style name="NegativeButtonStyle" parent="Widget.MaterialComponents.Button.TextButton">
<item name="android:textColor">#FF0000</item>
</style>
Found another solution for this with using MaterialComponents here: https://issuetracker.google.com/issues/116861837#comment9
<style name="Theme.Custom.Material.Alert.Dialog.Light" parent="Theme.MaterialComponents.Light.Dialog.Alert">
<item name="materialButtonStyle">#style/Widget.AppCompat.Button.Borderless</item>
</style>
<style name="Theme.Custom.Material.Base.Light" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="android:dialogTheme">#style/Theme.Custom.Material.Alert.Dialog.Light</item>
<item name="android:alertDialogTheme">#style/Theme.Custom.Material.Alert.Dialog.Light</item>
....
</style>
Though it is still not "intended behavior" to me.
If you don't want to use androidx.appcompat.app.AlertDialog, you can just redefine the style of the dialog buttons:
In your style.xml :
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
...
<item name="android:buttonBarButtonStyle">#style/DialogButton</item>
...
</style>
<style name="DialogButton" parent="Widget.MaterialComponents.Button.TextButton"/>
If you are using the com.android.support:design:28.0.0 library, using android.support.v7.app.AlertDialog works as expected.
I am using the material components theming for our app. Now we want a custom font, which I managed to apply almost everywhere with the theme below, which uses the various textAppearance... attributes defined by material components.
This works very well, and the theme is also applied to the AlertDialogs almost everywhere -- message text and buttons have the custom font, buttons have the correct accent colors etc.
Only the dialog title keeps the Roboto font, no matter what.
<!-- externalized font name for easier change -->
<string name="font_regular" translatable="false" tools:ignore="ReferenceType">#font/atma_regular</string>
<style name="Theme.App" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:textColorPrimary">#color/textColorPrimary</item>
<item name="android:textColorSecondary">#color/textColorSecondary</item>
<item name="textAppearanceHeadline1">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline2">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline3">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline4">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline5">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline6">#style/TextAppearance.App.Button</item>
<item name="textAppearanceSubtitle1">#style/TextAppearance.App.Subtitle1</item>
<item name="textAppearanceSubtitle2">#style/TextAppearance.App.Subtitle2</item>
<item name="textAppearanceBody1">#style/TextAppearance.App.Body1</item>
<item name="textAppearanceBody2">#style/TextAppearance.App.Body2</item>
<item name="textAppearanceButton">#style/TextAppearance.App.Button</item>
<item name="android:textAppearanceLarge">#style/TextAppearance.App.Large</item>
<item name="android:textAppearanceMedium">#style/TextAppearance.App.Medium</item>
<item name="android:textAppearanceSmall">#style/TextAppearance.App.Small</item>
</style>
<style name="TextAppearance.App.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1">
<item name="fontFamily">#string/font_regular</item>
<item name="android:fontFamily">#string/font_regular</item>
</style>
...
I tried to define an extra theme for the alert dialogs like so:
<style name="Theme.App" parent="Theme.MaterialComponents.Light.NoActionBar">
...
<item name="alertDialogTheme">#style/Theme.App.AlertDialog</item>
...
</style>
<style name="Theme.App.AlertDialog" parent="Theme.MaterialComponents.Light.Dialog.Alert">
<item name="android:windowTitleStyle">#style/TextAppearance.App.DialogWindowTitle</item>
</style>
<style name="TextAppearance.App.DialogWindowTitle" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
<item name="fontFamily">#string/font_regular</item>
<item name="android:fontFamily">#string/font_regular</item>
<item name="android:textSize">30sp</item>
</style>
But that resets the colors and fonts everywhere. The only thing that is applied, is the textSize.
It really shouldn't be so hard to achieve this, but I am out of ideas right now. I could apply the font programmatically, but that would be quite ugly.
As you mentioned the AlertDialog created by MaterialAlertDialogBuilder uses the style defined by the textAppearanceSubtitle1 attribute in your app theme.
Otherwise you can change the style used by the AlertDialog using something like:
new MaterialAlertDialogBuilder(MainActivity.this,
R.style.MyTitle_ThemeOverlay_MaterialComponents_MaterialAlertDialog)
.setTitle("Title")
.setMessage("Message......")
.setPositiveButton("ok", null)
.setNegativeButton("Cancel", null)
.show();
In your style you have to customize the materialAlertDialogTitleTextStyle attribute:
<style name="MyTitle_ThemeOverlay.MaterialComponents.MaterialAlertDialog" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="materialAlertDialogTitleTextStyle">#style/MyTitle_MaterialAlertDialog.MaterialComponents.Title.Text</item>
</style>
<style name="MyTitle_MaterialAlertDialog.MaterialComponents.Title.Text" parent="#style/MaterialAlertDialog.MaterialComponents.Title.Text">
<item name="android:textAppearance">#style/MyTitle_TextAppearance.MaterialComponents.Subtitle1</item>
</style>
<style name="MyTitle_TextAppearance.MaterialComponents.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1">
<item name="fontFamily">....</item>
<item name="android:fontFamily">....</item>
<item name="android:textStyle">.....</item>
</style>
Thanks to your question I realized that I was using the incorrect attribute to assign the title style (android:titleTextAppearance instead of android:windowTitleStyle).
It looks like your issue has been fixed in the meantime, as your exact code seems to work for me as of today.
Can we modify/custom ourBiometricPrompt?
For example right now i use smth like this:
BiometricPrompt.Builder(AppResources.appContext)
.setTitle("title")
.setSubtitle("subTitle")
.setDescription("description")
.setNegativeButton("Cancel", AppResources.appContext?.mainExecutor,
DialogInterface.OnClickListener { dialogInterface, i -> biometricCallback.onAuthenticationCancelled() })
.build()
.authenticate(CancellationSignal(), AppResources.appContext?.mainExecutor,
BiometricCallbackV28(biometricCallback))
Do I have the ability to change the style of the text, title, negativeButton color?
Update2: beta01
The change with the alpha version was that the fingerprint dialog uses android.app.AlertDialog and the new beta01 uses androidx.appcompat.app.AlertDialog which has a private style.
Then to override that style we have to override androidx.appcompat.R.attr.alertDialogTheme reference in our styles.xml, we can do it replacing <item name="android:alertDialogTheme">#style/CustomAlertTheme</item> by <item name="alertDialogTheme">#style/CustomAlertTheme</item> in my case thay I only wanted to change the button text color, I just added <item name="buttonBarNegativeButtonStyle">#style/NegativeButtonStyle</item> and the same for posivtive, because replacing alertDialogTheme changes other things that I did not want to.
My styles.xml now:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:textColor">#color/black</item>
<item name="android:buttonStyle">#style/WibleButtonStyle</item>
<item name="buttonBarNegativeButtonStyle">#style/NegativeButtonStyle</item>
</style>
<style name="NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textSize">16sp</item>
<item name="android:textColor">#color/dark_blue</item>
</style>
Update: beta01
This trick is not working anymore. I'll try if I can find another way to do it.
I found two ways to do it, none of these are specific for the BiometricPrompt, one is to override the theme button style:
<item name="android:buttonStyle">#style/CustomButtonStyle</item>
another option is to override your alert dialog theme:
AppTheme style
<item name="android:alertDialogTheme">#style/AlertDialogTheme</item>
<style name="AlertDialogTheme" parent="ThemeOverlay.AppCompat.Dialog.Alert">
<item name="android:buttonBarNegativeButtonStyle">#style/NegativeButtonStyle</item>
<item name="android:buttonBarPositiveButtonStyle">#style/PositiveButtonStyle</item>
</style>
<style name="NegativeButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textSize">10sp</item>
<item name="android:textColor">#color/primary_text</item>
</style>
<style name="PositiveButtonStyle" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
<item name="android:textColor">#color/primary_text</item>
</style>
And then you can apply a specific theme to a specific activity. Maybe they could open the API to allow styles, but I had to change the color because it was impossible to see the buttons (everything was white) and this is what I found to solve my problem. I hope it helps you.
You can't set properties on the prompt that aren't exposed through its Builder - the UI is provided by the system, and is designed to be uniform throughout all apps.
This is sort of the main point of this API, this way the user becomes familiar with the prompt and knows that whatever they're interacting with is safe to use.
Can we modify/custom our BiometricPrompt?
The BiometricPrompt uses the "buttonStyle" style that is set for your theme, which you can adjust in the styles.xml
Keep in mind that this is the default button style, so if you do not want other buttons to change you would have to assign buttons etc. their own style. (and dialogs etc.)
For example, if you only want the text color to be different for the BiometricPrompt, you could do something like this:
<style name="myTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="buttonStyle">#style/ButtonPrimaryStyle</item>
</style>
<style name="ButtonPrimaryStyle" parent="ButtonParentStyle">
<item name="android:textColor">454545</item>
</style>
<style name="ButtonPrimaryStyleMain" parent="ButtonPrimaryStyle">
<item name="android:textColor">e2e2e2</item>
</style>
This would make the BiometricPrompt have a dark grey text for the cancel button, while every button with the "ButtonPrimaryStyleMain" style will have a lightgrey, almost white, text color.
You would also have to assign this theme to your application in the manifest.
<application
android:theme="#style/myTheme"
I tried in many ways but I can't change the AlertDialog style from xml.
The result I would is to define an XML style for dialogs extending and overriding the default and then bind it in my theme, so all the alertDialogs will looks the same.
I tried:
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="android:alertDialogStyle">#style/pippo</item>
</style>
<style name="pippo" parent="#android:style/Theme.Dialog">
<item name="android:bottomBright">#android:color/holo_orange_dark</item>
<item name="android:bottomDark">#android:color/holo_orange_dark</item>
<item name="android:bottomMedium">#android:color/holo_orange_dark</item>
<item name="android:centerBright">#android:color/holo_orange_dark</item>
<item name="android:centerDark">#android:color/holo_orange_dark</item>
<item name="android:centerMedium">#android:color/holo_orange_dark</item>
<item name="android:fullBright">#android:color/holo_orange_dark</item>
<item name="android:fullDark">#android:color/holo_orange_dark</item>
<item name="android:topBright">#android:color/holo_blue_dark</item>
<item name="android:topDark">#android:color/holo_blue_dark</item>
</style>
and then I put in the manifest "AppTheme" as activity theme, but I still see normal alertdialogs.
Where I do wrong?
You can try something like this to apply the desired style:
AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style. pippo));