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>
Related
I am working with the Material Design components in the support library version 28.0.0.
I want to show a snackbar that when the text inside the action button is too long it be shown in a different line than the message of the snack bar.
Following the Material design documentation of these components it seems to be possible using the default snackbar as shown here:
https://material.io/design/components/snackbars.html#implementation
But using this code:
var snackbar:Snackbar = Snackbar.make(root, message, Snackbar.LENGTH_SHORT)
snackbar.setAction(action, View.OnClickListener { })
snackbar.show()
If the action text is long it doesn't move to the next line.
The root layout is a CoordinatorLayout.
So I do not know what I am missing in the snackbar to make it work.
Thanks!
The problem is actually an issue of android itself, the attribute loading from the default android dimen file is broken so the required attribute that is used to calculate the orientation of the elements of the snackbar is never set to the proper value. The issue has been informed and the solution will be pushed to the source code soon.
Workaround: set the attribute maxActionInlineWidth directly in your main theme and you can pickup the values from #dimen/design_snackbar_action_inline_max_width that is the one that should be used by android.
Example:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="maxActionInlineWidth">#dimen/design_snackbar_action_inline_max_width</item>
</style>
If you go through the answer to THIS question, you can do something like below code for the action button(actually textview):
var snackbar:Snackbar = Snackbar.make(root, message, Snackbar.LENGTH_SHORT)
val snackbarView = snackbar.view
val tv = snackbarView.findViewById<TextView>(android.support.design.R.id.snackbar_action)
tv.maxLines = 2
snackbar.show()
I've been trying to programatically inflate a linearlayout of buttons using a loop, but it doesn't show up in the ui at all. The array gets populated, however.
My button xml:
<Button xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/BlackKey">
</Button>
My style resource:
<style name="BlackKey">
<item name="android:layout_height">0dp</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_weight">2</item>
<item name="android:background">#color/black</item>
<item name="android:layout_margin">3dp</item>
</style>
My initialization code:
container = (FrameLayout) findViewById(R.id.mainframe);
public Button [] BLACKKEYS = new Button[5];
LinearLayout blackkeys = new LinearLayout(this);
blackkeys.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
blackkeys.setOrientation(LinearLayout.HORIZONTAL);
for (int i = 0; i < 8; i++){
Button newbutton = (Button) LayoutInflater.from(this).inflate(R.layout.blackkey, blackkeys, false);
blackkeys.addView(newbutton);
BLACKKEYS[i] = newbutton;
}
container.addView(blackkeys);
So I went ahead and tried the code you provided using Android Studio and I have also received a blank screen. Main point that I saw that caused this is in your BlackKey style, the layout_weight is provided, the layout_height is set to 0dp, and the layout_width is MATCH_PARENT, but the orientation is horizontal -- if ever the button shows up, this will make it only show a single button.
If how I understood on how you want this to show up (five buttons alongside each other in horizontal orientation, with equal widths) something like this:
Then you can just modify the BlackKey styles like this:
<style name="BlackKey">
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_weight">2</item>
<item name="android:background">#color/black</item>
<item name="android:layout_margin">3dp</item>
</style>
And also a tip, if ever you're using Android Studio, you can check first if the Button is showing in the Design Tab to see if it shows up properly on the screen. If it doesn't show up there, then try to modify it. Hope this helps you. If you have further questions, or if this is similar to the answer you're looking for but is not complete, just post a comment and I'll try to help you out. :)
color/colorPrimary is some orange color I want header has it. But I succeded to change header text color which is easy . I would like to change color of header background. This is what I have so far:
<style name="AppCompatAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:textColorPrimary">#color/colorPrimary</item>
<item name="android:windowTitleBackgroundStyle">#style/dialog_title_style</item>
<item name="android:alertDialogStyle">#style/AlertDialog_Sphinx</item>
<item name="colorAccent">#color/colorPrimary</item>
</style>
<style name="dialog_title_style" >
<item name="android:background">#color/colorPrimary</item>
<item name="android:padding">100dp</item>
</style>
<style name="AlertDialog_Sphinx">
<item name="android:fullDark">#color/colorPrimary</item>
<item name="android:topDark">#color/colorPrimary</item>
<item name="android:centerDark">#color/colorPrimary</item>
<item name="android:bottomDark">#color/colorPrimary</item>
<item name="android:fullBright">#color/colorPrimary</item>
<item name="android:topBright">#color/colorPrimary</item>
<item name="android:centerBright">#color/colorPrimary</item>
<item name="android:bottomBright">#color/colorPrimary</item>
<item name="android:bottomMedium">#color/colorPrimary</item>
<item name="android:centerMedium">#color/colorPrimary</item>
</style>
public class MyDialogFragment extends DialogFragment {
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder=new AlertDialog.Builder(getActivity(), R.style.AppCompatAlertDialogStyle).setTitle("Naslov")
.setMessage("Poruka......................................................")
.setIcon(android.R.drawable.ic_menu_help)
.setPositiveButton("OK",null);
return builder.create();
}
}
I'm using support version of AlertDialog.(23.1.0) This way dialog look more like dialog on newer version of android(Material Design)
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.1.0'
I want that header is of color/colorPrimary (orange) background.
In the latest API levels the alert dialog does not have a separate header. It has a single view and a divider which separates the header text and message. You can change the header text and message text colors and also the divider colour. Also, you can change the background of the entire alert dialog but not just the header section of it.
As a workaround what you can do is: Dont set header text but use an image with text in it followed by the message. This way the divider will vanish and the image will look like the header.
Basically a custom alert dialog.
Check this post to see how to add an image in alertdialogs.
You can create a custom view for the alert dialog.
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.dialog_layout, (ViewGroup) getCurrentFocus());
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(dialoglayout);
builder.show();
You can check out this material dialogs library here. It is very easy to use and also very customizable.
I have a ProgressDialog that looks like this on a Galaxy Tab 10.1"
and like this on a Galaxy Tab 7"
I want both Dialogs to look the same:
The closest that I get is by using the following style
<style name="popupStyle" parent="android:Theme.Dialog">
<item name="android:textColor">#FFFFFFFF</item>
<item name="android:background">#FF000000</item>
<item name="android:windowBackground">#android:color/transparent</item>
</style>
which results in this
So my questions are:
- How can I remove the border around the "Please wait" title?
- How can I change the overall border from blue to white?
- How can I adjust/reduce the width?
progressDialog = new ProgressDialog(context):
progressDialog.show();
TextView tv1 = (TextView) progressDialog.findViewById(android.R.id.message);
tv1.setTextSize(20);
tv1.setTypeface(yourCustomTF);
tv1.setText("your msg");
By doing it this way, you can change the message text and also customize the entire view by getting their components from the ProgressDialog that is shown. Remember, you can get the view Id by using findViewById() after progressDialog.show() because the view is generated after show().
This article may give you some hints on styling your dialogs and they will look the same on both targets.
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();
}
});
...
}