Program Club

Android Multiline Snackbar

proclub 2020. 10. 17. 12:33
반응형

Android Multiline Snackbar


http://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs에Snackbar 표시된대로 Android 디자인 지원 라이브러리의 새로운 기능을 활용 하여 여러 줄 스낵바를 표시 하려고합니다 .

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 에만 표시됩니다. 모든 행을 표시하려면 어떻게해야합니까?

추신 : 시도했는데 Toast모든 줄이 표시되었습니다.


maxLinesSnackbars Textview 속성을 설정하기 만하면됩니다.

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

앱의 values.xml에서 사용되는 미리 정의 된 값을 재정의 할 수 있습니다.

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

이 값은 기본적으로 Snackbar에서 사용됩니다.


이것에 대한 나의 발견은 다음과 같습니다.

Android는 여러 줄 스낵바를 지원하지만 여러 줄 스낵바의 높이가 80dp (거의 2 줄)가되어야한다는 설계 지침과 일치하는 최대 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();

"무작위 텍스트 \ n시기 ... " 만 볼 수 있습니다 . 이것은 디자인 라이브러리가 의도적으로 textview를 최대 2 줄로 강제한다는 것을 의미합니다.


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

스낵바에 포함 된 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;
}

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

이것은 나를 위해 작동합니다

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

머티리얼 디자인의 경우 참조는 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()

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

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

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.*

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

참고URL : https://stackoverflow.com/questions/30705607/android-multiline-snackbar

반응형