와챠의 우당탕탕 코딩 일기장
[Android/Kotlin]BottomSheetDialog/round corner/아래에 뜨는 다이얼로그로 선택하는 스피너 본문
코딩 일기장/Android(Kotlin)
[Android/Kotlin]BottomSheetDialog/round corner/아래에 뜨는 다이얼로그로 선택하는 스피너
minWachya 2022. 2. 19. 12:32반응형
아래 화면은 '동네 고영희' 앱 UI입니다!!!
결과 화면
- 스피너(TextView임) 클릭하면 아래에서 다이얼로그(BottomSheetDialog)가 나옴
- 아이템 선택 시 선택한 아이템으로 스피너(TextView) text 변경
- 아래로 드래그 시 다이얼로그 내려감(기본 기능임)
- 클릭 효과 적용
만들어보자~~~
요약:
- spinner 처럼 생긴 TextView 만들기
- res>drawable>spinner_bottom.xml 생성:레이아웃 맨 위의 오른쪽, 왼쪽 모서리를 둥글게 하기 위함
- res>layout>spinner_custom_layout.xml 생성: BottomSheetDialog Layout 만들기
- res>values>themes>themes.xml에 아래 style 추가: 뒷배경 투명 처리
- 1번의 TextView 클릭 시 bottomSheetDialog 보이기 + dialog에 sytle 추가
1, spinner 처럼 생긴 TextView 만들기
xml에서 Textview 부분만 가져왔다.
// TNR
<TextView
android:id="@+id/tnrSpinner"
android:hint="@string/cat_add_tnr_hint" // 수술 여부 선택
android:textSize="16sp"
style="@style/Widget.AppCompat.Spinner.Underlined" // 밑줄+스피너처럼 보이게 함
android:backgroundTint="@color/beige_E3DECF" // 밑줄 색 변경
android:layout_height="55dp"/>
2, res>drawable>spinner_bottom.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/white" />
<corners
android:topLeftRadius="15dp"
android:topRightRadius="15dp"
/>
</shape>
3, res>layout>spinner_custom_layout.xml 생성:
BottomSheetDialog Layout 만들기
- 체크 포인트!!
- ConstraintLayout
- app:behavior_peekHeight: 기본 높이 설정
- app:behavior_hideable="true": dialog 고정 조건, 항상 표시할 경우 peekHeight
- app:behavior_draggable="true": 사용자가 dialog의 높이를 손가락으로 조절 가능
- android:background="@drawable/spinner_bottom": 모서리 둥글게
- app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
- TextView
- 나는 이 BottomSheetDialog를 여러 곳에서 사용할 건데, 그때마다 아이템 수에 맞게 TextView를 동적 생성하는 게 귀찮아서... 최대 아이템 크기인 6에 맞춰서 TextView도 6개로 제작
- 아이템 추가할 때마다 TextView의 visibility, text 수정하려고 함
- 터치 효과를 위해 android:background="?attr/selectableItemBackground" 추가
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/bottomSheetDashBoardLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:behavior_hideable="true"
app:behavior_draggable="true"
android:background="@drawable/spinner_bottom"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="24dp"
android:textColor="@color/brown_473A22"
android:textSize="16sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imgClose"
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_close"
android:layout_marginTop="29dp"
android:layout_marginEnd="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text1"
android:visibility="gone"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/brown_473A22"
android:textSize="14sp"
android:layout_marginTop="31dp"
android:paddingStart="20dp"
android:paddingBottom="15dp"
android:paddingTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/text2"
android:visibility="gone"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/brown_473A22"
android:textSize="14sp"
android:paddingStart="20dp"
android:paddingBottom="15dp"
android:paddingTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text1"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/text3"
android:visibility="gone"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/brown_473A22"
android:textSize="14sp"
android:paddingStart="20dp"
android:paddingBottom="15dp"
android:paddingTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text2"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/text4"
android:visibility="gone"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/brown_473A22"
android:textSize="14sp"
android:paddingStart="20dp"
android:paddingBottom="15dp"
android:paddingTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text3"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/text5"
android:visibility="gone"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/brown_473A22"
android:textSize="14sp"
android:paddingStart="20dp"
android:paddingBottom="15dp"
android:paddingTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text4"
tools:ignore="RtlSymmetry" />
<TextView
android:id="@+id/text6"
android:visibility="gone"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/brown_473A22"
android:textSize="14sp"
android:paddingStart="20dp"
android:paddingBottom="15dp"
android:paddingTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text5"
tools:ignore="RtlSymmetry" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text6"/>
</androidx.constraintlayout.widget.ConstraintLayout>
4, res>values>themes>themes.xml에 아래 style 추가: 뒷배경 투명 처리
우리는 모서리를 둥글게 하고, 3번에서 backgroud를 통해 모서리를 둥글게 적용했지만...
막상 실행하면
https://stackoverflow.com/questions/10795078/dialog-with-transparent-background-in-android
위와 같은 문제 발생... corner 처리했는데도 그 뒷배경이 투명하지 않아서, 결국 모서리가 동그라미가 아니라 네모로 보이는...암튼 뒷배경을 이런 식으로 투명화 처리를 해줘야 한다.
<!--Custom BottomSheetDialog: corner 뒷배경 투명 처리-->
<style name="DialogCustomTheme" parent="android:Theme.Holo.Dialog.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
</style>
5, 1번의 TextView 클릭 시 bottomSheetDialog 보이기 + dialog에 sytle 추가
- 체크 포인트~
- arrTextViewId: bottomSheetLayout의 TextView id 배열!! 이걸 사용해서 아이템 수만큼 TextView가 보일 수 있도록 설정했다. 이걸 설정하는 함수가 setBottomSheetView()!!
- resources.getStringArray(R.array.cat_add3_tnr_array): res>values>spinner_array.xml을 만들어 배열을 만들어줘야 한다. 이때 title을 맨 위에 두어야 다이얼로그가 원하는 대로 만들어진다.
-
<?xml version="1.0" encoding="utf-8"?> <resources> <!--fragment_cat_add3--> <!--TNR 스피너 배멸--> <string-array name="cat_add3_tnr_array"> <item>TNR</item> <!--title--> <item>O</item> <item>X</item> <item>모름</item> </string-array> <!--선호 사료 스피너 배열--> <string-array name="cat_add3_food_array"> <item>선호 사료</item> <!--title--> <item>습식</item> <item>건식</item> <item>편식 안 함</item> <item>모름</item> </string-array> </resources>
-
package com.example.dongnaegoyang
import android.app.AlertDialog
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import com.example.dongnaegoyang.databinding.FragmentCatAdd3Binding
import com.google.android.material.bottomsheet.BottomSheetDialog
private const val TAG = "mmmCatAddFragment3"
private var _binding: FragmentCatAdd3Binding? = null
private val binding get() = _binding!!
class CatAddFragment3 : Fragment() {
// BottomDialog 위한 spinner_custom_layout.xml 아이디
val arrTextViewId = arrayListOf(R.id.title, R.id.text1, R.id.text2, R.id.text3, R.id.text4, R.id.text5, R.id.text6)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?,
): View {
_binding = FragmentCatAdd3Binding.inflate(inflater, container, false)
val view = binding.root
// TNR 선택 스피너 설정
val tnrBottomSheetView = layoutInflater.inflate(R.layout.spinner_custom_layout, null)
val tnrBottomSheetDialog = BottomSheetDialog(requireContext(), R.style.DialogCustomTheme) // dialog에 sytle 추가
val tnrArray = resources.getStringArray(R.array.cat_add3_tnr_array)
tnrBottomSheetDialog.setContentView(tnrBottomSheetView)
setBottomSheetView(tnrBottomSheetView, tnrArray, tnrBottomSheetDialog, binding.tnrSpinner)
binding.tnrSpinner.setOnClickListener {
tnrBottomSheetDialog.show()
}
// 선호 사료 선택 스피너 설정
val foodBottomSheetView = layoutInflater.inflate(R.layout.spinner_custom_layout, null)
val foodBottomSheetDialog = BottomSheetDialog(requireContext(), R.style.DialogCustomTheme) // dialog에 sytle 추가
val foodArray = resources.getStringArray(R.array.cat_add3_food_array)
foodBottomSheetDialog.setContentView(foodBottomSheetView)
setBottomSheetView(foodBottomSheetView, foodArray, foodBottomSheetDialog, binding.foodSpinner)
binding.foodSpinner.setOnClickListener {
foodBottomSheetDialog.show()
}
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
// 스피너 선택 설정
private fun setBottomSheetView(bottomSheetView: View, arr: Array<String>, dialog: BottomSheetDialog, spinner: TextView) {
for (i in arr.indices) {
val textView = bottomSheetView.findViewById<TextView>(arrTextViewId[i]) // TextView를 차례로 가져옴
textView.text = arr[i] // text 추가
textView.visibility = View.VISIBLE // TextView가 보이게 함
textView.setOnClickListener { // 클릭 시 1번의 spinner인 척하는 TextView의 text 변경+dialog 내려가기
spinner.text = arr[i]
dialog.dismiss()
}
}
// X버튼 누르면 닫힘
val closeButton = bottomSheetView.findViewById<ImageView>(R.id.imgClose)
closeButton.setOnClickListener {
dialog.dismiss()
}
}
}
반응형
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[Android/Kotlin]사진 최대 선택 개수 제한하기/limit the number of selected photo (0) | 2022.02.27 |
---|---|
[Android/Kotlin]Custom Dialog (0) | 2022.02.26 |
[Android/Kotlin]Spinner hint/Spinner underline (0) | 2022.02.18 |
[Kotlin]let/with/run/apply/also (0) | 2022.02.08 |
[Android/Kotlin]코루틴(Coroutine) 정리 (0) | 2022.02.07 |
Comments