101

我正在尝试利用SnackbarAndroid 设计支持库中的新功能来显示多行小吃栏,如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();

它只显示First line...在我的 Nexus 7 上。如何让它显示所有行?

PS:我试过Toast了,它显示了所有行。

4

19 回答 19

248

只需设置maxLinesSnackbars Textview 的属性

View snackbarView = snackbar.getView();
TextView textView = (TextView) snackbarView.findViewById(android.support.design.R.id.snackbar_text);
textView.setMaxLines(5);  // show multiple line

如果您使用的是更新的"com.google.android.material:material:1.0.0"依赖项,那么您将使用这个:com.google.android.material.R.id.snackbar_text访问 Snackbar 的 TextView。

你甚至可以使用R.id.snackbar_text。这对我有用。

于 2015-07-15T11:24:03.107 回答
33

可以覆盖应用程序的 values.xml 中使用的预定义值

<integer name="design_snackbar_text_max_lines">5</integer>

Snackbar 默认使用此值。

于 2015-09-22T15:02:52.877 回答
14
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();
于 2016-08-15T05:48:38.753 回答
11

这是我对此的发现:

Android 确实支持多行小吃吧,但它的最大限制为 2 行,这与设计指南相匹配,其中说多行小吃吧的高度应为 80dp(几乎 2 行)

为了验证这一点,我使用了 cheesesquare android 示例项目。如果我使用以下字符串:

Snackbar.make(view, "Random Text \n When a second snackbar is triggered while the first is displayed", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();

在这种情况下,我可以看到带有第二行文本的多行小吃店,即“当触发第二个小吃店时”但是如果我将此代码更改为以下实现:

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();

我只能看到“随机文本\nWhen ... ”。这意味着设计库有意强制 textview 最多为 2 行。

于 2015-06-08T09:53:13.100 回答
9

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>

enter image description here

Note: it requires the version 1.2.0 of the library.

于 2019-11-02T12:35:54.910 回答
7

在 kotlin 中,您可以使用扩展。

// SnackbarExtensions.kt

fun Snackbar.allowInfiniteLines(): Snackbar {
    return apply { (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.isSingleLine = false }
}

用法:

Snackbar.make(view, message, Snackbar.LENGTH_LONG)
                        .allowInfiniteLines()
                        .show()
于 2019-12-24T19:56:27.087 回答
7

对于材料设计,参考是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()
于 2019-05-28T21:48:45.923 回答
4

在 Kotlin 中,你可以这样做

Snackbar.make(root_view, "Yo\nYo\nYo!", Snackbar.LENGTH_SHORT).apply {
    view.snackbar_text.setSingleLine(false)
    show()
}

你也可以setSingleLine(false)maxLines = 3.

Android Studio 应该会提示您添加

import kotlinx.android.synthetic.main.design_layout_snackbar_include.view.*

编辑

我无法让它再次工作,所以我将分享我认为用 Kotlin 编写的最干净的方法,其他一些人已经分享过:

import com.google.android.material.R as MaterialR

Snackbar.make(root_view, "Yo\nYo\nYo!", Snackbar.LENGTH_SHORT).apply {
    val textView = view.findViewById<TextView>(MaterialR.id.snackbar_text)
    textView.setSingleLine(false)
    show()
}

于 2018-12-20T09:49:06.047 回答
3

涉及硬编码快餐栏包含的 textview 的资源 ID 的建议的替代方法是迭代以查找 TextView。从长远来看,它更安全,并且可以让您更新支持库,而不必担心 ID 更改。

例子:

 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;
}
于 2016-07-12T17:34:33.590 回答
2

迟到了,但可能对某人有帮助:

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();
}
于 2017-10-05T16:14:40.867 回答
2

这对我有用

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();
于 2017-06-04T11:15:34.347 回答
2

我没有使用 setMaxLines,而是使用 setSingleLine 使 textview 换行到其内容。

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();
于 2017-06-01T10:51:55.150 回答
1

一种不会崩溃的方法,以防新版本的库发生变化:

Snackbar.make(...).setAction(...) {
    ...
}.apply {
    (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.setSingleLine(false)
}.show()

还有一种不使用 id 的方法,将 Snackbar 中的所有 TextView 设置为具有无限多行:

@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()

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());
}
于 2019-06-13T09:04:19.973 回答
1

我可以建议你使用com.google.android.material.snackbar.Snackbar. 这是谷歌推荐的方式。首先你必须添加你的小吃店。

final Snackbar snackbar = Snackbar.make(
            findViewById(R.id.activity_layout),
            "snackbar explanation text \n multilines \n\n here",
            Snackbar.LENGTH_INDEFINITE)
            .setAction(R.string.action_settings, new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // your action here
                }
            });

然后添加多行支持

TextView messageView = snackbar.getView().findViewById(R.id.snackbar_text);
                        messageView.setMaxLines(4);
                        

最后展示小吃店。

snackbar.show();
于 2021-01-17T09:39:20.967 回答
0

只是一个快速评论,如果您使用com.google.android.material:material的前缀或包R.id应该是com.google.android.material

val snackbarView = snackbar.view
val textView = snackbarView.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)
textView.maxLines = 3
于 2019-09-13T18:14:10.297 回答
0

2021 年 Kotlin 中的答案com.google.android.material:material:1.4.0

isSingleLine = false是必需的,以及maxLines = 5

Snackbar.make(view, "line 1\nline 2", BaseTransientBottomBar.LENGTH_INDEFINITE)
    .apply {
        this.view.findViewById<TextView>(com.google.android.material.R.id.snackbar_text)?.apply {
            maxLines = 5
            isSingleLine = false
        }
    }
    .show()
于 2021-07-03T09:21:49.257 回答
0

小吃店高度调整:

val sMsg = "Msg\n\n"
val sOk = getString(R.string.ok)
val sMoreLines = StringBuilder()
for (iCtr in 1..6) {
    sMoreLines.append("\n")                 
}
Snackbar
.make(
    this.requireActivity().findViewById(android.R.id.content),
    sMsg,
    Snackbar.LENGTH_INDEFINITE)        
.setAction("$sMoreLines$sOk\n$sMoreLines") {
    // ...
}
.show()
于 2022-02-27T10:55:05.830 回答
0

为避免其他答案的不稳定,可以使用updateMaxLine,如果 Google 决定更改文本视图的 id,此解决方案不太可能中断)

val snackBar = Snackbar.make(view, message, duration)
 snackBar.view.allViews.updateMaxLine(5)
 snackBar.show()

请注意,此选项将更新 Snakbar 视图中所有文本视图的最大行(我认为这并不重要)

将此添加为扩展名

private fun <T> Sequence<T>.updateMaxLine(maxLine : Int) {
    for (view in this) {
        if (view is TextView) {
            view.maxLines = maxLine
        }
    }
}

在此处输入图像描述

于 2020-08-16T14:35:15.700 回答
0

因此,当我使用来自谷歌的最新材料设计库时,com.google.android.material:material:1.1.0 我使用了下面的简单代码片段来解决允许在小吃店中添加更多行的问题。希望它对新开发人员也有帮助。

TextView messageView = snackbar.getView().findViewById(R.id.snackbar_text);
messageView.setMaxLines(5);
于 2020-03-19T09:06:21.617 回答