问题
I'm trying to leverage new Snackbar
from Android Design Support Library to display multiline snackbar, as shown in http://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs:
import android.support.design.widget.Snackbar;
final String snack = "First line\nSecond line\nThird line";
Snackbar.make(mView, snack, Snackbar.LENGTH_LONG).show();
It displays only First line...
on my Nexus 7. How to make it display all lines?
PS: I tried Toast
and it displayed all lines.
回答1:
Just set the maxLines
attribute of Snackbars Textview
View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5); // show multiple line
If you're using the more recent "com.google.android.material:material:1.0.0"
dependency, then you will use this: com.google.android.material.R.id.snackbar_text
to access the Snackbar's TextView.
回答2:
One can override the predefined value used for that in values.xml of the app
<integer name="design_snackbar_text_max_lines">5</integer>
This value is used by Snackbar by default.
回答3:
Here is my finding on this :
Android does support multiline snackbars but it has a max limit of 2 lines which matches the design guideline where it says that the height of multiline snack bar should be 80dp (almost 2 lines)
To verify this, i used the cheesesquare android sample project. If i use following string:
Snackbar.make(view, "Random Text \n When a second snackbar is triggered while the first is displayed", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
In this case, i can see the multiline snack bar with the text of 2nd line, i.e. "When a second snackbar is triggered" but if i change this code to following implementation:
Snackbar.make(view, "Random Text \n When \n a second snackbar is triggered while the first is displayed", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
I can only see the "Random Text\nWhen ...". This means that design library is intentionally forcing the textview to be of max 2 lines.
回答4:
Snackbar snackbar = Snackbar.make(view, "Text",Snackbar.LENGTH_LONG).setDuration(Snackbar.LENGTH_LONG);
View snackbarView = snackbar.getView();
TextView tv= (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
tv.setMaxLines(3);
snackbar.show();
回答5:
An alternative to the suggestions that involve hardcoding the resource ID for the textview contained by the snackbar is to iterate to find the TextView. It's safer long-term and lets you update the support library with minimal fear of the ID changing.
Example:
public static Snackbar getSnackbar(View rootView, String message, int duration) {
Snackbar snackbar = Snackbar.make(rootView, message, duration);
ViewGroup snackbarLayout = (ViewGroup) snackbar.getView();
TextView text = null;
for (int i = 0; i < snackbarLayout.getChildCount(); i++) {
View child = snackbarLayout.getChildAt(i);
// Since action is a button, and Button extends TextView,
// Need to make sure this is the message TextView, not the
// action Button view.
if(child instanceof TextView && !(child instanceof Button)) {
text = (TextView) child;
}
}
if (text != null) {
text.setMaxLines(3);
}
return snackbar;
}
回答6:
Instead of using setMaxLines, i use setSingleLine to make the textview wrap to its content.
String yourText = "First line\nSecond line\nThird line";
Snackbar snackbar = Snackbar.make(mView, yourText, Snackbar.LENGTH_SHORT);
TextView textView =
(TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text);
textView.setSingleLine(false);
snackbar.show();
回答7:
this works for me
Snackbar snackbar = Snackbar.make(mView, "Your text string", Snackbar.LENGTH_INDEFINITE);
((TextView) snackbar.getView().findViewById(android.support.design.R.id.snackbar_text)).setSingleLine(false);
snackbar.show();
回答8:
For Material Design, the reference is com.google.android.material.R.id.snackbar_text
val snack = Snackbar.make(myView, R.string.myLongText, Snackbar.LENGTH_INDEFINITE).apply {
view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text).maxLines = 10
}
snack.show()
回答9:
Late, but might be helpful to someone:
public void showSnackBar(String txt, View view){
final Snackbar snackbar = Snackbar.make(view,txt,Snackbar.LENGTH_INDEFINITE)
.setAction("OK", new View.OnClickListener() {
@Override
public void onClick(View view) {
//do something
}
});
View view = snackbar.getView();
TextView textView = (TextView) view.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5);
snackbar.show();
}
回答10:
A way to do it which won't crash in case things change on newer versions of the library :
Snackbar.make(...).setAction(...) {
...
}.apply {
(view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.setSingleLine(false)
}.show()
And a way to do it without having ids being used, setting all TextViews in the Snackbar to have unlimited multi-lines :
@UiThread
fun setAllTextViewsToHaveInfiniteLinesCount(view: View) {
when (view) {
is TextView -> view.setSingleLine(false)
is ViewGroup -> for (child in view.children)
setAllTextViewsToHaveInfiniteLinesCount(child)
}
}
Snackbar.make(...).setAction(...) {
...
}.apply {
setAllTextViewsToHaveInfiniteLinesCount(view)
}.show()
The same function in Java:
@UiThread
public static void setAllTextViewsToHaveInfiniteLines(@Nullable final View view) {
if (view == null)
return;
if (view instanceof TextView)
((TextView) view).setSingleLine(false);
else if (view instanceof ViewGroup)
for (Iterator<View> iterator = ViewGroupKt.getChildren((ViewGroup) view).iterator(); iterator.hasNext(); )
setAllTextViewsToHaveInfiniteLines(iterator.next());
}
回答11:
In Kotlin, you can just do
Snackbar.make(rootView, "Yo!", Snackbar.LENGTH_LONG).apply {
view.snackbar_text.setSingleLine(false)
show()
}
You can replace setSingleLine(false)
with maxLines = 3
if you'd like.
Android Studio should prompt you to add
import kotlinx.android.synthetic.main.design_layout_snackbar_include.view.*
回答12:
Just a quick comment, if you are using com.google.android.material:material
the prefix or package for R.id
should be com.google.android.material
val snackbarView = snackbar.view
val textView = snackbarView.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)
textView.maxLines = 3
回答13:
With the Material Components Library you can define it using with the snackbarTextViewStyle
attribute in the app theme:
<style name="AppTheme" parent="Theme.MaterialComponents.*">
...
<item name="snackbarTextViewStyle">@style/snackbar_text</item>
</style>
<style name="snackbar_text" parent="@style/Widget.MaterialComponents.Snackbar.TextView">
...
<item name="android:maxLines">5</item>
</style>
Note: it requires the version 1.2.0 of the library.
来源:https://stackoverflow.com/questions/30705607/android-multiline-snackbar