[android] 커스텀 스낵바(custom Snackbar) 레이아웃 예제 및 총정리
안드로이드 스낵바(custom Snackbar)
스낵바(Snackbar)는 휴대폰 화면하단에 위치하는 메세지 박스입니다. 물론 토스트와 같이 스낵바의 위치를 변경할 수 있습니다. 스낵바는 자주 사용하는 토스트(Toast)와 유사합니다. 스낵바와 토스트의 가장 큰 차이점은 사용자의 액션을 받아서 처리하느냐 안하느냐의 차이라고 생각됩니다. 토스트는 사용자에게 정보성으로 제공되는 메세지인 반면에 스낵바는 메세지를 주는 동시에 경고성 알림을 주고 사용자에게 확인버튼을 제공하여 클릭을 유도할 수 있습니다. 사용자가 인지하고 넘어가는지 확인하는 방법으로 사용하면 유용합니다. 간단한 약관의 동의페이지를 스낵바로 만들어서 사용할 수도 있겠지요.
■토스트(Toast)
Toast.makeText(getApplicationContext(),"Hello",Toast.LENGTH_SHORT).show();
■스낵바(Snackbar)
Snackbar.make(view, "Replace with your own action"
, Snackbar.LENGTH_LONG).setAction("Action", null).show();
기본적인 사용방법으로 사용시 액션이벤트(setAciotn)를 추가할 수 있습니다. 아래 예제는 10초 간 나타났다 사라집니다.
Snackbar.make(view, "리뷰를 쓰러갈까요?", 10000).setAction("YES", new View.OnClickListener()
{
@Override
public void onClick(View v)
{
//마켓 링크 호출
}
}).show();
기본적인 사용방법으로 사용시 스낵바의 백그라운드 색상을 변경하는 방법입니다. setBackgroudColor를 사용해도 되며 다른 메소드도 지원합니다.
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar snackbar;
snackbar = Snackbar.make(view, "종료할까요?",Snackbar.LENGTH_LONG)
.setActionTextColor(Color.BLUE).setAction("예", new View.OnClickListener()
{
@Override
public void onClick(View v)
{
finish();
}
});
View snackView = snackbar.getView();
snackView.setBackgroundColor(Color.parseColor("#D47FA6"));
snackbar.show();
}
});
커스텀 스낵바
다음으로 스낵바를 커스텀하여 사용하여봅니다. 샘플 예제로 탈출(EXIT) 레이아웃을 하나 생성하였습니다.
[exit_snackbar.xml]
<?xml version="1.0" encoding="utf-8"?>
<!-- android:background="@android:color/transparent"-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/bannerLayout"
android:background="@drawable/bg_eixt_expane_shape_radius"
android:gravity="center">
<LinearLayout
android:orientation="horizontal"
android:layout_width="wrap_content"
android:id="@+id/topLayout"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:gravity="center_vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:id="@+id/imageView3"
android:background="@drawable/baseline_power_settings_new_24"/>
<TextView
android:id="@+id/textView21"
android:layout_width="254dp"
android:layout_height="wrap_content"
android:text="@string/go_out"
android:layout_marginLeft="5dp"
android:textSize="20sp"
android:textColor="#ffffff"
android:layout_gravity="center_vertical"
android:layout_marginRight="10dp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="10dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="10dp"
android:background="@color/colorAccent"/>
<LinearLayout
android:id="@+id/bottomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="1dp"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="@drawable/update_bg_left_shape_radius"
android:gravity="center_vertical|center"
android:layout_marginRight="2.5dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/answer_no"
android:textColor="@color/colorContent"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout4"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="@drawable/update_bg_right_shape_radius"
android:gravity="center_vertical|center"
android:layout_marginLeft="2.5dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/answer_yes"
android:textColor="@color/colorContent"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mainLayout"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/baseline_dialpad_24" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
커스텀 스낵바를 사용하기위해서는 스낵바를 노출할 뷰(대상)이 필요합니다. 보통 MainActivity의 레이아웃를 지정합니다.
private View snackBarLayout;
snackBarLayout = findViewById(R.id.mainLayout);
스낵바를 사용해보면 패딩값이 적용되어 있는 것을 확인할 수 있습니다. 패딩값을 제거하는 방법입니다. setPadding()메소드를 사용하여 0으로 값을 설정합니다.
globalSnackbar = Snackbar.make(snackBarLayout, "", Snackbar.LENGTH_INDEFINITE);
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) globalSnackbar.getView();
layout.setPadding(0,0,0,0);
setBackgroudTint()메소드는 exit_snackbar.xml 레이아웃의 백그라운드 색상을 변경하는 것이 아닙니다. 우리는 스낵바 자체의 레이아웃 안에 exit_snackbar.xml 레이아웃을 추가 하는 개념이라고 생각하시면 이해하기 쉽습니다. 즉 exit_snackbar.xml 레이아웃을 감싸는 레이아웃이 있다는 얘기지요. 스낵바의 BackgrountTint의 기본값은 values.xml에 설정되어 있습니다.
<color name="design_snackbar_background_color">#323232</color>
투명하게 변경하고 싶은 경우 아래 컬러를 하나 추가하여 사용하세요.
<color name="snackbar_transparent_bg_color">#00ffffff</color>
globalSnackbar.setBackgroundTint(ContextCompat.getColor(this, R.color.snackbar_transparent_bg_color));
globalSnackbar.setBackgroundTint(ContextCompat.getColor(this, R.color.colorAccent));
globalSnackbar.show();
[MainActivity.class]
private Snackbar globalSnackbar;
private View snackBarLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
snackBarLayout = findViewById(R.id.mainLayout);
setSupportActionBar(toolbar);
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action"
, Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
});
}
private void dismissGlobalSnackbar(){
if(globalSnackbar!=null) {
globalSnackbar.dismiss();
}
}
private void showAlarmSnackbar() {
globalSnackbar = Snackbar.make(snackBarLayout, "", Snackbar.LENGTH_INDEFINITE);
Snackbar.SnackbarLayout layout = (Snackbar.SnackbarLayout) globalSnackbar.getView();
//layout.setBackgroundResource(R.drawable.backgroud_xml);
layout.setPadding(0,0,0,0); //마진값 없애기
//inflate view
View snackView = getLayoutInflater().inflate(R.layout.exit_snackbar, null);
LinearLayout linearLayout3 = snackView.findViewById(R.id.linearLayout3);
LinearLayout linearLayout4 = snackView.findViewById(R.id.linearLayout4);
linearLayout3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismissGlobalSnackbar();
}
});
linearLayout4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
layout.addView(snackView, 0);
//레이아웃 백그라운드 색상변경
//globalSnackbar.setBackgroundTint(ContextCompat.getColor(this, R.color.colorAccent));
globalSnackbar.show();
}
[build.gradle]
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
defaultConfig {
applicationId "test.app"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment:2.3.1'
implementation 'androidx.navigation:navigation-ui:2.3.1'
//AdMob Ads SDK
implementation 'com.google.android.gms:play-services-ads:19.5.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
[참고 자료]
https://stackoverflow.com/questions/41317923/android-snackbar-layout
[관련 자료]
https://stackoverflow.com/questions/33885424/how-to-create-android-snackbar-with-custom-layout
https://www.tutorialspoint.com/how-to-how-to-customize-snackbar-s-layout-in-android
https://stackoverflow.com/questions/32453946/how-to-customize-snackbars-layout
https://everyshare.tistory.com/47
[다른 글 더 보기]