[오늘 배운 내용]
-1- Spinner
- Spinner란 dropDown 형식으로 항목을 나타내는 ViewItem이다.
Spinner 생성하기
- 기본적으로 만들 수 있는 Spinner를 생성하려면 가장먼저 Item을 클릭했을 시 DropDown되는 아이템들을 지정해주자
- res/values 폴더 하위에 array.xml 파일을 생성해주고 해당 파일안에 DropDown 시 보여질 아이템들을 넣어주자
Array.xml
<resources>
<string-array name="spinner_main_menu">
<item>home</item>
<item>work</item>
<item>other</item>
<item>custom</item>
</string-array>
</resources>
- Spinner가 들어갈 main.xml 로 가서, Spinner를 만들고 Spinner를 통해 TextView의 Text를 바꿀 수 있도록 TextView도 추가해준다.
<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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Spinner
android:id="@+id/spinner"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="293dp"
android:padding="10dp"
android:background="@drawable/spinner_bg"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_View"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="248dp"
android:layout_marginTop="30dp"
android:text="textView"
android:textSize="20sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- main.kt Activity로 이동해서 xml에서 생성해놓은 Spinner와 adapter를 통해서 연결해주고 클릭 리스너를 달아주면 된다.
- setOnClickListener는 AdapterView의 인터페이스가 아닌 Kotlin에서 제공하는 확장 함수이므로 OnItemSelectedListener와 구분해야 한다. setOnClickListener도 람다식으로 간결하고 편리하게 작동할 수 있다고 하는데, 복잡한 로직을 처리하기 위해서는 OnItemSelected 함수를 사용해야 한다고 한다.
- DropDown 메뉴들의 아이템 Position은 0 부터 시작한다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val spinner = findViewById<Spinner>(R.id.spinner)
val textView = findViewById<TextView>(R.id.text_View)
spinner.adapter = ArrayAdapter.createFromResource(this,R.array.spinner_main_menu,android.R.layout.simple_spinner_item)
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
when (position) {
0 -> {
textView.text = "1번 선택"
}
1 -> {
textView.text = "2번 선택"
}
2 -> {
textView.text = "3번 선택"
}
3 -> {
textView.text = "4번 선택"
}
else -> {
textView.text = "선택되지 않음"
}
}
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
}
}
-2- Spinner CustomAdapter
- 여러가지 시도해보았으나 Spinner에 아이콘을 넣으면 DropDown에 나오는 아이템들도 같은 아이콘을 달고 나와서 다른 블로그에서 만든 CustomAdapter를 들고왔다.
- 해당 블로그에서 코드를 가져왔는데, 확장함수도 명확하게 배우지 않은 상태라서 배우고 난 뒤에 다시 뜯어봐야겠다..
https://vintageappmaker.tistory.com/360
- 완벽하게 이해 X 복붙해놓았음 이해하려고 시간을 굉장히 많이 보냈는데 아직 이해하기가 어려워서 코드만 작성해두고 추후에 수정.
res/drawable - spinner_bg.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="#333333"/>
<corners android:radius="3dp" />
</shape>
</item>
<item android:gravity="center_vertical|right" android:right="8dp">
<layer-list>
<item android:width="12dp" android:height="12dp" android:gravity="center" android:bottom="10dp">
<rotate
android:fromDegrees="45"
android:toDegrees="45">
<shape android:shape="rectangle">
<solid android:color="#eeeeee" />
<stroke android:color="#eeeeee" android:width="1dp"/>
</shape>
</rotate>
</item>
<item android:width="20dp" android:height="11dp" android:bottom="21dp" android:gravity="center">
<shape android:shape="rectangle">
<solid android:color="#333333"/>
</shape>
</item>
</layer-list>
</item>
</layer-list>
res/layout - spinner_drop_down_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/text_drop_down_item"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="#333333"
android:ellipsize="marquee"
android:gravity="left|center_vertical"
android:minWidth="130dp"
android:paddingStart="20dp"
android:singleLine="true"
android:textColor="#eeeeee"
android:textSize="12dp" />
</LinearLayout>
res/layout - main.xml
<Spinner
android:id="@+id/spinner"
android:layout_width="200dp"
android:layout_height="60dp"
android:layout_marginStart="30dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="170dp"
android:background="@drawable/spinner_bg"
android:padding="10dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
mainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val spinner = findViewById<Spinner>(R.id.spinner)
val textView = findViewById<TextView>(R.id.text_View)
val category = mutableListOf("없음","outer","tops","bottoms","shorts","hats")
// custom
spinner.setCustomAdapter(this,category)
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) {
when (p2){
0 -> { }
1 -> { textView.text = category[p2] + " 선택"}
2 -> { textView.text = category[p2] + " 선택"}
3 -> { textView.text = category[p2] + " 선택"}
else -> { textView.text = category[p2] + " 선택"}
}
}
override fun onNothingSelected(p0: AdapterView<*>?) {
textView.text = "선택되지 않음"
}
}
}
}
fun View.dpToPx(dp:Float): Int = context.dpToPx(dp)
fun Context.dpToPx(dp:Float) : Int = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dp,resources.displayMetrics).toInt()
fun View.setHeight(context: Context,value: Int){
val lp = layoutParams
lp?.let {
lp.height = dpToPx(value.toFloat())
layoutParams = lp
}
}
fun Spinner.setCustomAdapter(context: Context, list : MutableList<String>,unselectedTitle : String = "선택"){
class CustomSpinnerAdapter : BaseAdapter {
var list : MutableList<String> = mutableListOf<String>()
var context: Context
var unselectedTitle : String
constructor(context: Context,list:MutableList<String>,unselectedTitle: String){
this.context = context
this.list = list
this.unselectedTitle = unselectedTitle
}
override fun getCount(): Int {
return list.size
}
override fun getItem(n: Int): Any {
return list[n]
}
override fun getItemId(p0: Int): Long {
return 0
}
override fun getView(n: Int, p1: View?, p2: ViewGroup?): View {
val v = LayoutInflater.from(context).inflate(R.layout.spinner_drop_down_bg,null)
v.findViewById<TextView>(R.id.text_first)?.apply {
text = "선택"
text = list[n]
if (p2 is Spinner){
background = context.getDrawable(R.drawable.spinner_bg)
if (p2.selectedItemPosition < 0){
p2.setHeight(context,60)
setTextColor(Color.WHITE)
text = unselectedTitle
textSize = 18f
}
}
}
return v
}
}
adapter = CustomSpinnerAdapter(context,list,unselectedTitle)
this.setSelection(-1)
}
-3-
[오늘 복습한 내용]
1. 복습은 아니고 노트프로그램을 정했다 TIL 작성과 별개로 노트도 작성해보려고 마음 먹었다. 크롬 북마크 수가 너무 많기도 해서 노트앱에 별도로 정리할 수 있는 저장공간으로 써보려고 한다.
[오류,에러 등등]
1. 특이점 없음
[느낀 점]
1. 점점 더 어려워 지는 것 같아서 집중 하는 시간을 늘리고 열심히 따라가야겠다.
2. 잡생각이 너무 많아서 좀 단순하게 생각하는 습관을 들여야겠다.
3. Adapter와 연결하는 부분은 항상 어려운 느낌인데 얼른 익숙해지도록 노력해야겠다.
[Reference]
// Spinner
https://vintageappmaker.tistory.com/360
https://aries574.tistory.com/381?category=375976
'TIL' 카테고리의 다른 글
[TIL] Kotlin ViewModel / LiveData / Observer Pattern (0) | 2023.09.13 |
---|---|
[TIL] Kotlin SharedPreference (0) | 2023.09.12 |
[TIL] Kotlin RecyclerView ViewType 나누기 (0) | 2023.09.08 |
[TIL] Fragment ResultListener로 데이터 옮기기 (0) | 2023.09.06 |
[TIL] Dialog Fragment / Dialog Fragment 데이터 Fragment로 이동 (0) | 2023.09.06 |