Button style in AlertDialogs - android

Does anyone know how to override the default style for AlertDialog buttons? I've looked through the Android source for themes and styles and experimented with different things but I haven't been able to find a way that works.
What I've got below works for changing the backgrounds, but doesn't do anything with the buttons. myTheme is applied to the whole <application> via the manifest. (Some other items were deleted for clarity, but they only relate to the title bar.)
<style name="myTheme" parent="android:Theme">
<item name="android:buttonStyle">#style/customButtonStyle</item>
<item name="android:alertDialogStyle">#style/dialogAlertTheme</item>
</style>
<style name="dialogAlertTheme" parent="#android:style/Theme.Dialog.Alert">
<item name="android:fullDark">#drawable/dialog_loading_background</item>
<item name="android:topDark">#drawable/dialog_alert_top</item>
<item name="android:centerDark">#drawable/dialog_alert_center</item>
<item name="android:bottomDark">#drawable/dialog_alert_bottom</item>
<!-- this last line makes no difference to the buttons -->
<item name="android:buttonStyle">#style/customButtonStyle</item>
</style>
Any ideas?

Given that MrSnowflake's reasoning is inaccurate, I'm taking the freedom to provide another answer.
There is something wrong with the markup in Steve Haley's question, and it is mixing up alertDialogStyle and alertDialogTheme, most likely because of the fact that alertDialogTheme was introduced long after alertDialogStyle was around.
So even if #android:style/Theme.Dialog.Alert is available on your Andoid platform, you still can't utilize its expressional power by hooking a cusomized version back into your own theme unless your Android platform supports an android:alertDialogTheme attribute/item for themes. (It may or may not be the case that such inconsistent Android versions exist, I don't know for sure. But the markup used in the question suggests that it does.)
In the question's markup, the parent="#android:style/Theme.Dialog.Alert" will do nothing except creating the illusion that you're customizing the alert dialog theme when you're really only customizing the alert dialog style.
This is how the markup should look like; not all Android versions support all features.
<style name="myTheme" parent="android:Theme">
<item name="android:buttonStyle">#style/customButtonStyle</item>
<item name="android:alertDialogStyle">#style/dialogAlertStyle</item>
<item name="android:alertDialogTheme">#style/dialogAlertTheme</item>
</style>
<style name="dialogAlertStyle" parent="#android:style/AlertDialog">
<item name="android:fullDark">[...]</item>
[...]
</style>
<style name="dialogAlertTheme" parent="#android:style/Theme.Dialog.Alert">
<item name="android:windowBackground">[...]</item>
[...]
</style>
Customizing the alert dialog style has been around for quite some time but is limited to providing (background) drawables for "fullDark", "topDark" etc.
Customizing the alert dialog theme opens a method to provide attributes such as windowBackground, windowTitleStyle and such, but as stated before, you need an Android version which supports the alertDialogThem attribute/item for themes. I can't figure out exactly when this was introduced but it hasn't been Android 2.2 and Eclipse will tell you anyway...
I don't have the resources to validate MrSnowflake's conclusion that it's impossible to style alert dialog buttons in XML, but unless we're facing one of those somewhat nasty aspects of Android where a feature is really missing, I find it unlikely.
As a matter of fact, what's missing in the question is the most relevant part in this respect, namely
<style name="customButtonStyle" />
so the conclusion that alert dialog buttons do not obey the Widget.Button is not yet proven from my point of view.
Consolidated conclusion: The abilities to style alert dialogs independently of other widgets is limited in Android but getting more powerful as new versions improve in this respect.

Try this:
<item name="buttonBarStyle">#style/Widget.AppCompat.ButtonBar</item>
<item name="buttonBarButtonStyle">#style/AppTheme.Button</item>
<item name="buttonBarPositiveButtonStyle">#style/YoursTheme</item>
<item name="buttonBarNegativeButtonStyle">#style/YoursTheme</item>
<item name="buttonBarNeutralButtonStyle">#style/YoursTheme</item>

You can override "buttonBarButtonStyle" instead of "buttonStyle" like this:
<style name="dialogAlertTheme" parent="#android:style/Theme.Dialog.Alert">
<item name="android:buttonBarButtonStyle">#style/customButtonStyle</item>
</style>

If you're using Material Components:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:alertDialogTheme">#style/AlertDialogTheme.Light</item>
</style>
<style name="AlertDialogTheme.Light" parent="ThemeOverlay.MaterialComponents.Dialog.Alert" >
<item name="android:buttonBarButtonStyle">#style/InsertCustomButtonStyleHere</item>
</style>
This will keep your theme's colors but replace the style of the buttons, for instance to match Widget.MaterialComponents.Button.TextButton.

I made a method like this that will change the default button colors and background
public static void setDefaultColorTextForDialogButton(AlertDialog alertDialog, Resources r) {
Button b;
b= alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
if(b != null) {
b.setTextColor(r.getColor(R.color.default_text));
b.setBackgroundColor(Color.WHITE);
}
b = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if(b != null) {
b.setTextColor(r.getColor(R.color.default_text));
b.setBackgroundColor(Color.WHITE);
}
b = alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL);
if(b != null) {
b.setTextColor(r.getColor(R.color.default_text));
b.setBackgroundColor(Color.WHITE);
}
}
This could be useful for some people!!!

See all other anwsers below.
Incorrect:
I guess you have to implement your own Dialog class.

This allowed me to customize my AlertDialog buttons and layout.
private void openLookupTableEditDialog() {
AlertDialog.Builder openLookupTableEditDialog = new AlertDialog.Builder(this);
View v = this.getLayoutInflater().inflate(R.layout.lookup_table_edit_dialog, null);
openLookupTableEditDialog.setView(v);
final AlertDialog alert = openLookupTableEditDialog.create();
openLookupTableEditDialog.setTitle("Lookup Table Edit");
Button btnSpecies = v.findViewById(R.id.btnSpeciesLookupEdit);
Button btnLocation = v.findViewById(R.id.btnLocationLookupEdit);
Button btnSampler = v.findViewById(R.id.btnSamplerLookupEdit);
Button btnExit = v.findViewById(R.id.btnCloseLookupTableEdit);
alert.setView(v);
alert.show();
btnSpecies.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
editSpeciesTable();
alert.dismiss();
}
});
btnSampler.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
editSamplerTable();
alert.dismiss();
}
});
btnLocation.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
editLocationTable();
alert.dismiss();
}
});
btnExit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
alert.dismiss();
}
});
...
}

Related

How to apply custom font style/ family to alert dialogs in entire app through styles

I want to change the font face of alert dialog in entire app. How to achieve it through XML(styles). Please help me with some solution .Thank You
Follow the below method,
public void createDialog()
{
Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.your_dialog);
final FontChangeCrawler fontChanger = new FontChangeCrawler(context.getAssets(), Constant.arialRoundedFont);
fontChanger.replaceFonts((ViewGroup) dialog.findViewById(android.R.id.content));
dialog.setCancelable(false);
dialog.show();
}
->apply this method for all your dialogs by creating this method in your Util class and use it globally.
this will work for you.
You need to add Calligraphy in build.gradle, Please refer Calligraphy for more detail.
dependencies {
compile 'uk.co.chrisjenx:calligraphy:2.3.0'
}
Use below code in your Application file:
CalligraphyConfig.initDefault(CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/roboto_bold.ttf")
.setFontAttrId(R.attr.fontPath)
.build()
Create single instance of dialog using below code or where ever you are creating new dialog.
progressDialog = ProgressDialog(ContextThemeWrapper(context, R.style.AlertProgressDialogCustom))
Put below style in style.xml
<style name="DialogTextButton" parent="#android:style/TextAppearance.Holo.Medium">
<item name="fontPath">fonts/open_sans.ttf</item>
<item name="android:textColor">#color/black</item>
</style>
<style name="AlertProgressDialogCustom" parent="#android:style/Theme.Material.Light.Dialog">
<item name="android:textAppearanceMedium">#style/DialogTextButton</item>
<item name="android:subtitleTextAppearance">#style/DialogTextButton</item>
<item name="android:titleTextAppearance">#style/DialogTextButton</item>
<item name="android:textColor">#color/black</item>
<item name="android:textColorPrimary">#color/black</item>
<item name="android:colorAccent">#color/btn_picker_color</item>
<item name="android:progressTint">#color/btn_picker_color</item>
<item name="android:textAppearance">#style/DialogTextButton</item>
</style>
Let me know if you are still facing issue.

Android - how to set theme values programmatically (from database values)

Is it possible if my theme values are downloadable from server then my mobile theme will change according to what I specify from it?
Example if I have columns [colorPrimary] and [colorAccent] from server then after downloading values, my app theme colors will change accordingly.
This is my current theme.
<style name="Base.Theme.Design" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#013034</item>
<item name="colorPrimaryDark">#013034</item>
<item name="colorAccent">#1490a0</item>
<item name="android:textColorHint">#9e9e9e</item>
</style>
Note: For all downvotes, please leave comment for improvement of this post. Thanks.
You can use Firebase remote config to apply that, for example if you have multiple theme options for your app like "Base.Theme.Design_A" and "Base.Theme.Design_B" which are already built-in your app. You can switch between and apply one of these themes by checking a remote property in Firebase remote config. Also you can change old value and fetch the remote values and activate them (not with style file)
<defaultsMap>
<entry>
<!-- color entries -->
<entry>
<key>colorPrimary</key>
<value>#013034</value>
</entry>
<entry>
<key>colorPrimaryDark</key>
<value>#013034</value>
</entry>
To change your app's colour dynamically, for elaborate implementations refer to this
There is a way to change your App's theme dynamically.
You need put two the themes in your styles.xml in advance, like this:
<style name="AppThemeA" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#aba424</item>
<item name="colorPrimaryDark">#9f2020</item>
<item name="colorAccent">#2a6c29</item>
</style>
<style name="AppThemeB" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#706464</item>
<item name="colorPrimaryDark">#831444</item>
<item name="colorAccent">#183150</item>
</style>
And use one of them in your codes.
For example, there is button in your MainActivity, if you click it, your theme will change to AppThemeA, so you need do this in your MainActivity's OnCreate:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
if ("A".Equals(Intent.GetStringExtra("Theme")))
{
SetTheme(Resource.Style.AppThemeA);
}
else if("B".Equals(Intent.GetStringExtra("Theme"))) {
SetTheme(Resource.Style.AppThemeB);
}
SetContentView(Resource.Layout.Main);
Button button = FindViewById<Button>(Resource.Id.bt);
button.Click += (sender, e) => {
Intent intent= new Intent(this, typeof(MainActivity));
intent.PutExtra("Theme","A");
StartActivity(intent);
Finish();
};
}

How to prevent my snackbar text from being truncated on Android?

I am displaying a snackbar with a fairly long text message and on the phone in portrait mode it looks fine.
But on the tablet it seems to only allow 1 line of text so it gets ellipsis-ed
Is there anyway I can get it to be 2 line in tablet landscape?
What's important and not stated in other answers is that you need to use Snackbar's view.
So:
Snackbar snackbar = Snackbar.make(rootView, R.string.message, Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView snackTextView = (TextView) snackbarView.findViewById(com.google.android.material.R.id.snackbar_text);
snackTextView.setMaxLines(2);
snackbar.show();
Note: This may also help with devices with lower screen density.
P.S If you're not using AndroidX (which is recommended), and are still using the legacy support libraries, please use android.support.design.R.id.snackbar_text instead of com.google.android.material.R.id.snackbar_text for getting the Snackbar's internal TextView.
You can reference the SnackBar's TextView like this:
TextView tv = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
And then operate on the TextView itself by changing its max lines:
tv.setMaxLines(3)
Based on Snackbar source code you can see that on devices with width more or equal than 600 dp they change max lines to 1. So You can also just add:
<integer name="design_snackbar_text_max_lines">3</integer>
into your res\values\*.xml values
A more elaborate and thorough example with context would be this:
// Create on click listener
final OnClickListener positiveButtonClickListener = new OnClickListener()
{
#Override
public void onClick(View v)
{
// Do your action - e.g. call GooglePlay to update app
openGooglePlayAppUpdate();
}
};
// Create snack bar instance
Snackbar sBar = Snackbar.make(findViewById(R.id.some_view_to_bind), // You bind here e.g. layout, or form view
R.string.snack_bar_message,
Snackbar.LENGTH_INDEFINITE)
// Set text and action to the snack bar
.setAction(android.R.string.ok, positiveButtonClickListener);
// Now get text view of your snack bar ...
TextView snckBarTv = (TextView) offerUpdate.getView().findViewById(android.support.design.R.id.snackbar_text);
snckBarTv.setMaxLines(5); // ... and set max lines
sBar.show(); // and finally display snack bar !
For those using Kotlin you can make use of extensions
fun Snackbar.setMaxLines(lines: Int): Snackbar = apply {
view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text).maxLines = lines
}
For me, the best solution was auto-size within 2 lines:
<style name="ThemeOverlay.MyApp.SnackBar.Text" parent="#style/Widget.MaterialComponents.Snackbar.TextView" >
<item name="autoSizeStepGranularity">0.5dp</item>
<item name="autoSizeMaxTextSize">16dp</item>
<item name="autoSizeMinTextSize">10dp</item>
<item name="autoSizeTextType">uniform</item>
</style>
You can also increase the max number of lines or change any other TextView attribute:
<style name="ThemeOverlay.MyApp.SnackBar.Text" parent="#style/Widget.MaterialComponents.Snackbar.TextView" >
<item name="android:maxLines">3</item>
</style>
And customize the button and paddings:
<style name="ThemeOverlay.MyApp.SnackBar.Button" parent="#style/Widget.MaterialComponents.Button.TextButton.Snackbar" >
<item name="android:paddingStart">16dp</item>
<item name="android:paddingEnd">16dp</item>
<item name="android:textSize">14dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:letterSpacing">0.0</item>
</style>
<style name="ThemeOverlay.MyApp.SnackBar" parent="#style/Widget.MaterialComponents.Snackbar" >
<item name="android:paddingStart">8dp</item>
<item name="android:paddingEnd">8dp</item>
</style>
Your theme:
<style name="Theme.MyApp" parent="#style/Theme.MaterialComponents.DayNight.NoActionBar">
<item name="snackbarStyle">#style/ThemeOverlay.MyApp.SnackBar</item>
<item name="snackbarButtonStyle">#style/ThemeOverlay.MyApp.SnackBar.Button</item>
<item name="snackbarTextViewStyle">#style/ThemeOverlay.MyApp.SnackBar.Text</item>
</style>

Creating a translucent "dialog activity"

I have a dialog-style activity that appears over my main activity in an Android application. How can I get the background to be translucent? Not transparent, but translucent - say 70% opaque. I've tried applying this theme to the activity:
<style name="Theme.Transparent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
and several variations on this but still the dialog activity appears 100% opaque. Also, the layout xml of the activity itself (and elements displayed on it), specify a background of "#70000000".
For totally transparent dialog you can use this :
Step 1> Create a colors.xml file in the ‘values’ folder under ‘res’ and add the following line..
<drawable name="transparent">#00000000</drawable>
Step 2> Create a styles.xml file in the ‘values’ folder under ‘res’ and the following lines…
<style name="Transparent">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">
#android:style/Animation.Translucent
</item>
<item name="android:windowBackground">#drawable/transparent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:colorForeground">#fff</item>
</style>
(I guess the tags and attributes are self explanatory…)
Step 3> Actually, that's it……………………
Let’s add this to a dialog…..
Step 4> Create a class with the following lines……
public class DialogBox extends Dialog {
public DialogBox(Context context, int theme) {
super(context, theme);
setContentView(R.layout.dialog);
okButton = (Button) findViewById(R.id.dialog_OkButton);
setListeners();
}
}
(Make sure you create a layout for the dialog)
Step 5> Next create an activity class as follows….
public class T_Temp extends Activity {
private DialogBox dialog;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
dialog = new DialogBox(this, R.style.Transparent);
dialog.show();
}
}
or you can use this to make dialog attractive to add blur effect ....
Just check this out: there is near about 30% transparency...
dialog = new AlertDialog.Builder(WordCube.this)
.setTitle(WordCube.this.getResources().getString(R.string.app_name))
.setMessage(s)
.setIcon(R.drawable.logo)
.setPositiveButton(R.string.btn_close, null)
.show();
Below shows the code needed to add blur and remove dimming of the background (as I think the blur looks nicer when the background is well lit).
view plaincopy to clipboardprint?
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
lp.dimAmount=0.0f;
dialog.getWindow().setAttributes(lp);
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

XML attributes for text color of alert dialog

I'm applying a theme:
<style name="myAlertTheme" parent="#android:style/AlertDialog">
<item name="android:textColor">#ff000000</item>
</style>
<style name="RadioButton" parent="#android:style/Widget.CompoundButton.RadioButton">
<item name="android:textColor">#ff000000</item>
</style>
<style name="HSDroidStyle" parent="android:Theme">
<item name="android:background">#ffd3d3d3</item>
<item name="android:textColor">#ff000000</item>
<item name="android:textSize">20dp</item>
<item name="android:radioButtonStyle">#style/RadioButton</item>
</style>
But when I create an Alert, the text shows up as white instead of black. To create the alert I'm using:
AlertDialog alertDialog = new AlertDialog.Builder(
new ContextThemeWrapper(act, R.style.myAlertTheme)).create();
alertDialog.setTitle(title);
alertDialog.setMessage(msg);
alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (exitOnFailure) mainAct.finish();
return;
} });
alertDialog.show();
Now the "OK" in the button changes if I change the size in the myAlertTheme, but not the title or the text. So I'm guessing that there is some other textColor attribute that addresses this. I've tried most of the ones I can think of, but none of them work.
Any ideas?
hooked82 is right. Prior to Honeycomb, Android did not support text styling properly for AlertDialogs. You could apply styles to an AlertDialog, but it would ignore the text styles.
Here's a good SO answer that would prove to be a good solution for you: How to change theme for AlertDialog
Here's a really useful blog post that uses the propsed solution above to style an AlertDialog properly.
AFAIK there isn't a way to modify the Title/Message text colors (Please correct me if I'm wrong). So one way of doing this would be to create a custom view for your AlertDialog and do something like the following:
LayoutInflater factory = LayoutInflater.from(this);
final View layout = factory.inflate(R.layout.alert_layout, null);
alertDialog.setView(layout);
Try to declare the AlertDialog using this statement:
AlertDialog alertDialog = new AlertDialog(mContext, R.style.myAlertTheme);

Categories

Resources