Я пытаюсь использовать новое Snackbar
из библиотеки поддержки дизайна Android для отображения многострочной закусочной, как показано в 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
и он отобразил все строки.
Ответы:
Просто установите
maxLines
атрибут Snackbars TextviewView 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
для доступа к TextView Snackbar.Вы можете использовать даже
R.id.snackbar_text
. это работа для меня.источник
Можно переопределить предопределенное значение, используемое для этого в values.xml приложения.
<integer name="design_snackbar_text_max_lines">5</integer>
Это значение используется Snackbar по умолчанию.
источник
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();
источник
Вот мой вывод по этому поводу:
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();
В этом случае я могу видеть многострочную закусочную с текстом 2-й строки, т.е. «Когда срабатывает вторая закусочная», но если я изменю этот код на следующую реализацию:
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();
Я могу видеть только «Случайный текст \ nКогда ... ». Это означает, что библиотека дизайна намеренно заставляет текстовое представление иметь максимум 2 строки.
источник
Для материального дизайна ссылка
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()
источник
Альтернативой предложениям, включающим жесткое кодирование идентификатора ресурса для текстового представления, содержащегося в снекбаре, является итерация для поиска TextView. Это более безопасно в долгосрочной перспективе и позволяет обновлять библиотеку поддержки с минимальным опасением изменения идентификатора.
Пример:
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; }
источник
findViewsWithText
, так как вы уже знаете текст. Это решение может сломаться в нескольких ситуациях (например, если наше текстовое представление становится потомком дочернего элемента макета закусочной).snackbarLayout.getChildAt()
что никогда не вернетсяTextView
.Вместо использования setMaxLines я использую setSingleLine, чтобы текстовое представление переносилось на его содержимое.
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();
источник
это работает для меня
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();
источник
Поздно, но может быть кому-то полезно:
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(); }
источник
С помощью библиотеки компонентов материала вы можете определить его, используя
snackbarTextViewStyle
атрибут в теме приложения:<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>
Примечание : требуется версия библиотеки 1.2.0 .
источник
В котлине можно использовать расширения.
// 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()
источник
В Котлине вы можете просто сделать
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() }
источник
snackbar_text
.java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setSingleLine(boolean)' on a null object reference
implementation 'com.google.android.material:material:1.1.0'
и ваш Snackbar тот самыйcom.google.android.material.snackbar.Snackbar
? Если нет, попробуйтеandroid.support.design.R.id.snackbar_text
использовать идентификатор ресурса.Способ сделать это, который не приведет к сбою, если что-то изменится в более новых версиях библиотеки:
Snackbar.make(...).setAction(...) { ... }.apply { (view.findViewById<View?>(R.id.snackbar_text) as? TextView?)?.setSingleLine(false) }.show()
И способ сделать это без использования идентификаторов, установив для всех TextView в Snackbar неограниченное количество строк:
@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()); }
источник
Небольшой комментарий, если вы используете
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
источник
так как я использую новейшую библиотеку дизайна материалов от Google,
com.google.android.material:material:1.1.0
и я использовал простой следующий фрагмент кода ниже, чтобы разрешить больше строк в снек-баре. надеюсь, что это поможет и новым разработчикам.TextView messageView = snackbar.getView().findViewById(R.id.snackbar_text); messageView.setMaxLines(5);
источник
Чтобы избежать ошибочности других ответов
updateMaxLine
, это решение вряд ли сломается, если Google решит изменить идентификатор текстового представления)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 } } }
источник