https://goni95.tistory.com/173
1️⃣BottomSheetDialogFragment
BottomSheetDialogFragment는 떠 있는 Dialog 대신 BottomSheetDialog를 사용해 하단 시트를 보여주는 DialogFragment 버전입니다. 즉, 밑에서 올라오는 팝업창이라고 생각하면 됩니다.
예제를 확인하기 전 Databinding과 Style Resource에 대한 내용이 포함되어 있으니, 참고해주시기 바랍니다.
1. 모듈 수준의 build.gradle 파일에 material 종속성 추가가 필요합니다.
implementation 'com.google.android.material:material:1.5.0'
2. BottomSheetDialogFragment에서 사용하려는 XML 레이아웃 파일을 작성합니다.
bottom_sheet_food_ntr_irdnt.xml
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="model"
type="***.***.FoodNtrIrdntModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="@+id/foodNtrIrdnt_beginYear_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:text="@{@string/begin_year_desc_info(model.beginYear)}"
android:textColor="@color/color_on_secondary"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_fat_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_serving_weight_textView"
tools:text="구축년도" />
<TextView
android:id="@+id/foodNtrIrdnt_description_kor_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="50dp"
android:layout_marginEnd="10dp"
android:maxLines="2"
android:text="@{model.descriptionKOR}"
android:textColor="@color/color_on_secondary"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="식품 명" />
<TextView
android:id="@+id/foodNtrIrdnt_company_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:maxLines="1"
android:text="@{model.company}"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_description_kor_textView"
tools:text="업체 명" />
<TextView
android:id="@+id/foodNtrIrdnt_serving_weight_textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="10dp"
android:text="@{@string/serving_weight_desc_info(model.servingCount, model.servingWeight * model.servingCount)}"
android:textColor="@color/color_on_secondary"
android:textSize="12sp"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_beginYear_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_company_textView"
tools:text="1회 제공량" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_carbohydrate_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/carbohydrate"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_protein_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_serving_weight_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_carbohydrate_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/carbohydrate_info(model.carbohydrate * model.servingCount)}"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_carbohydrate_textView"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_carbohydrate_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_carbohydrate_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_protein_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/protein"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_fat_textView"
app:layout_constraintStart_toEndOf="@+id/foodNtrIrdnt_carbohydrate_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_carbohydrate_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_protein_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/protein_info(model.protein * model.servingCount)}"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_protein_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_protein_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_protein_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_fat_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/fat"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintStart_toEndOf="@+id/foodNtrIrdnt_protein_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_carbohydrate_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_fat_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/fat_info(model.fat * model.servingCount)}"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_fat_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_fat_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_fat_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_sugar_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/sugar"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_salt_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_carbohydrate_info_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_sugar_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/sugar_info(model.sugar * model.servingCount)}"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_sugar_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_sugar_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_sugar_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_salt_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/salt"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_cholesterol_textView"
app:layout_constraintStart_toEndOf="@+id/foodNtrIrdnt_sugar_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_sugar_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_salt_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/salt_info(model.salt * model.servingCount)}"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_salt_textView"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_salt_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_salt_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_cholesterol_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/cholesterol"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_fat_textView"
app:layout_constraintStart_toEndOf="@+id/foodNtrIrdnt_salt_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_sugar_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_cholesterol_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/cholesterol_info(model.cholesterol * model.servingCount)}"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_cholesterol_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_cholesterol_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_cholesterol_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_saturatedFattyAcid_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/saturated_fatty_acid"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_transFat_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_description_kor_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_sugar_info_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_saturatedFattyAcid_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/saturated_fatty_acid_info(model.saturatedFattyAcid * model.servingCount)}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_saturatedFattyAcid_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_saturatedFattyAcid_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_saturatedFattyAcid_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_transFat_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/trans_fat"
app:layout_constraintEnd_toStartOf="@+id/foodNtrIrdnt_calorie_textView"
app:layout_constraintStart_toEndOf="@+id/foodNtrIrdnt_saturatedFattyAcid_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_saturatedFattyAcid_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_transFat_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/trans_fat_info(model.transFat * model.servingCount)}"
app:layout_constraintBottom_toBottomOf="@+id/foodNtrIrdnt_saturatedFattyAcid_info_textView"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_transFat_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_transFat_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_transFat_textView" />
<!-- ========== 구분선 ========== -->
<TextView
android:id="@+id/foodNtrIrdnt_calorie_textView"
style="@style/Theme.CalIngredientFood.Dome.Top.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:backgroundTint="@color/color_on_secondary"
android:text="@string/calorie"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_fat_textView"
app:layout_constraintStart_toEndOf="@+id/foodNtrIrdnt_transFat_textView"
app:layout_constraintTop_toTopOf="@+id/foodNtrIrdnt_saturatedFattyAcid_textView" />
<TextView
android:id="@+id/foodNtrIrdnt_calorie_info_textView"
style="@style/Theme.CalIngredientFood.Dome.Bottom.TextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:backgroundTint="@color/color_on_light_secondary"
android:text="@{@string/calorie_info(model.calorie * model.servingCount)}"
app:layout_constraintBottom_toBottomOf="@+id/foodNtrIrdnt_saturatedFattyAcid_info_textView"
app:layout_constraintEnd_toEndOf="@+id/foodNtrIrdnt_calorie_textView"
app:layout_constraintStart_toStartOf="@+id/foodNtrIrdnt_calorie_textView"
app:layout_constraintTop_toBottomOf="@+id/foodNtrIrdnt_calorie_textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
해당 레이아웃 파일에서 사용되는 Style Resource는 아래와 같습니다.
styles.xml
<!--
식품 영양정보 상제 페이지(bottomSheet)에 쓰이는 TextView style
-->
<style name="Theme.CalIngredientFood.Dome.Top.TextView" parent="Widget.AppCompat.TextView">
<item name="android:background">@drawable/bg_dome_top_design</item>
<item name="android:textColor">@color/color_primary</item>
<item name="android:textSize">13sp</item>
<item name="android:gravity">center</item>
<item name="android:padding">3dp</item>
</style>
<!--
식품 영양정보 상제 페이지(bottomSheet)에 쓰이는 TextView style
-->
<style name="Theme.CalIngredientFood.Dome.Bottom.TextView" parent="Widget.AppCompat.TextView">
<item name="android:background">@drawable/bg_dome_bottom_design</item>
<item name="android:textColor">@color/color_on_light_secondary</item>
<item name="android:textSize">11sp</item>
<item name="android:gravity">center</item>
<item name="android:padding">3dp</item>
</style>
<!--
식품 영양정보 상제 페이지(bottomSheet)의 Rounded corners / NavigationBarColor 설정
bottomSheetStyle : custom design을 적용
windowIsFloating : true - dialog가 자식 사이즈만큼 사용 / false : dialog가 전체 화면을 사용
false인 경우 navigationBarColor 속성이 적용됨
navigationBarColor : navigationBar 색상을 설정
-->
<style name="Theme.CalIngredientFood.BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
<item name="bottomSheetStyle">@style/Theme.CalIngredientFood.BottomSheet.Modal</item>
<item name="android:windowIsFloating">false</item>
<item name="android:navigationBarColor">@color/color_primary</item>
</style>
<!--
BottomSheet에는 Persistent, Modal 두 종류 존재
Persistent : 특정 화면의 Layout에 속하도록 하며, Behavior 속성을 설정해야함
Modal : 안드로이드의 Toast처럼 어디에서나 표시할 수 있고, BottomSheetDialogFragment 사용
-->
<style name="Theme.CalIngredientFood.BottomSheet.Modal" parent="Widget.Design.BottomSheet.Modal">
<item name="android:background">@drawable/bg_bottom_sheet_design</item>
</style>
그래픽 또는 이미지를 선택적으로 표현할 수 있는 xml 파일인 drawable은 아래와 같습니다.
bg_bottom_sheet_design.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/color_primary" />
<corners
android:topLeftRadius="30dp"
android:topRightRadius="30dp" />
</shape>
</item>
<item
android:top="15dp"
android:left="150dp"
android:right="150dp"
android:height="4dp">
<shape android:shape="rectangle">
<solid android:color="@color/color_shadow_dark" />
<corners
android:radius="10dp" />
</shape>
</item>
</layer-list>
bg_dome_top_design.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/color_primary" />
<corners
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
bg_dome_bottom_design.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:top="-2dp">
<shape>
<solid android:color="@android:color/transparent" />
<stroke
android:width="1dp"
android:color="@color/color_primary" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp" />
</shape>
</item>
</layer-list>
layout, style, drawable에서 사용되는 color, string resource는 아래와 같습니다.
<string name="serving_weight_desc_info">%s회 제공량 : %s(g)</string>
<string name="begin_year_desc_info">구축년도 : %s년</string>
<string name="calorie">칼로리</string>
<string name="carbohydrate">탄수화물</string>
<string name="protein">단백질</string>
<string name="fat">지방</string>
<string name="sugar">당류</string>
<string name="salt">나트륨</string>
<string name="cholesterol">콜레스테롤</string>
<string name="saturated_fatty_acid">포화지방산</string>
<string name="trans_fat">트랜스지방산</string>
<string name="calorie_info">%1$.2f(kcal)</string>
<string name="carbohydrate_info">%1$.2f(g)</string>
<string name="protein_info">%1$.2f(g)</string>
<string name="fat_info">%1$.2f(g)</string>
<string name="sugar_info">%1$.2f(g)</string>
<string name="salt_info">%1$.2f(mg)</string>
<string name="cholesterol_info">%1$.2f(mg)</string>
<string name="saturated_fatty_acid_info">%1$.2f(g)</string>
<string name="trans_fat_info">%1$.2f(g)</string>
<color name="color_primary">#EFEEEE</color>
<color name="color_shadow_dark">#D1CDC7</color>
<color name="color_on_secondary">#585858</color>
<color name="color_on_light_secondary">#787878</color>
3. BottomSheetDialogFragment를 상속받아 정의
FoodNtrIrdntBottomSheet.kt
/**
* Gon [22.01.24] : Google Material Design에서 제공하는 BottomSheetDialogFragment를 상속받아 구현한 FoodNtrIrdntBottomSheet
* internal constructor() : 내부 생성자가 있는 class에서 접근제한자를 internal로 하여 외부에선 개체를 만들지 못하게하는 효과
*/
class FoodNtrIrdntBottomSheet internal constructor(private val model: FoodNtrIrdntModel) : BottomSheetDialogFragment() {
companion object {
/**
* Gon [22.01.24] : 여러 번 표시되지 않도록 SingleTon Pattern으로 구현
*/
fun newInstance(model: FoodNtrIrdntModel) : FoodNtrIrdntBottomSheet =
FoodNtrIrdntBottomSheet(model).also {
DebugLog.d("called : ${hashCode()}")
}
}
/**
* Gon [22.01.24] : BottomSheetDialogFragment의 테마 설정 (Theme.CalIngredientFood.BottomSheetDialog)
*/
override fun getTheme(): Int = R.style.Theme_CalIngredientFood_BottomSheetDialog
private lateinit var binding : BottomSheetFoodNtrIrdntBinding
private fun getDataBinding(): BottomSheetFoodNtrIrdntBinding =
BottomSheetFoodNtrIrdntBinding.inflate(layoutInflater)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = getDataBinding()
binding.lifecycleOwner = this
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.model = this.model
}
}
4. 사용
사용 시엔 FoodNtrIrdntBottomSheet의 인스턴스를 생성해 show() 메서드를 통해 FragmentManager와 TAG를 넘기면 됩니다. Constants 파일에 따로 TAG를 관리하거나 하드코딩하면 됩니다.
FoodNtrIrdntBottomSheet.newInstance(model)
.show(requireActivity().supportFragmentManager, Constants.BOTTOM_SHEET_TAG)
디자인과 관련된 코드들 중 공통으로 사용될 수 있는 부분들을 include 등을 이용해서 수정하면 더 깔끔하고 보기좋게 만들 수 있을 것 같아 기회가 된다면 수정해서 변경해보겠습니다.
2️⃣Bottomsheetbehavior
CoordinatorLayout에서 자식 뷰에 대한 플러그인 중 하나이기 때문에 CoordinatorLayout으로 감싸진 형태여야 합니다.
자식 뷰에 아래와 같이 속성을 설정해주면 하단에서 펼쳐지듯이 동작하도록 할 수 있습니다.
//Behavior를 적용하기 위해선 id가 필요
android:id="@+id/bottomsheet"
//하단 시트로 사용할 View가 기본적으로 미리보기가 가능하도록 사용
//미리보기 비활성화( true ) | 미리보기 활성화( false )
app:behavior_hideable="false"
//미리보기를 활성화한 경우 기본적으로 노출될 값
app:behavior_peekHeight="50dp"
//behavior를 적용시키는 코드입니다.
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
이외에 추가적인 속성은 디벨로퍼 사이트에서 XML attributes에서 확인할 수 있습니다.
https://developer.android.com/reference/com/google/android/material/bottomsheet/BottomSheetBehavior
View Controller에서 Behavior를 지정해주면 기본적인 준비는 끝났습니다.
val sheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottomsheet))
sheetBehavior.isGestureInsetBottomIgnored = true
여기에 Bottomsheetbehavior의 상태값에 따라 변화를 주고 싶다면 아래와 같이 addBottomSheetCallback을 통해 이벤트 알림을 위한 콜백을 추가해 이용하면 됩니다.
sheetBehavior.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
//slideOffest 0.0 ~ 1.0(접힘 ~ 펼침)
//위 값을 이용해 펼쳐질 수록 디자인을 변경하는 등의 작업을 하면 됩니다.
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
when (newState) {
STATE_EXPANDED -> {
//완전히 펼쳐진 상태
}
STATE_DRAGGING -> {
//드래그 되고있는 상태
}
STATE_SETTLING -> {
//드래그되가 고정된 상태
}
STATE_HALF_EXPANDED -> {
//절반이 펼쳐진 상태
}
STATE_COLLAPSED -> {
//접혀있는 상태
}
STATE_HIDDEN -> {
아래로 숨겨져 보이지 않는 상태
}
}
}
})
'Android > Android의 모든 것' 카테고리의 다른 글
👋Android의 모든 것 : 1️⃣SharedPreference, 2️⃣DataStore (0) | 2022.03.21 |
---|---|
👋Android의 모든 것 : 1️⃣안드로이드의 애니메이션의 모든 것 (0) | 2022.03.17 |
👋Android의 모든 것 : 1️⃣Activity 상태 변경 처리, 2️⃣Task & Back Stack, 3️⃣Parcelable 및 Bundle (0) | 2022.03.16 |
👋Android의 모든 것 : 1️⃣Activity와 Fragment 생명주기, 2️⃣ Activity와 Framgnet 차이 (0) | 2022.03.16 |
👋Android의 모든 것 : 1️⃣ANR, 2️⃣Intent, 3️⃣화면 모드 전환, 강제 종료 시 상태 및 데이터 유지 (0) | 2022.03.16 |