와챠의 우당탕탕 코딩 일기장
[Android/Kotlin]Custom View 만들기/Spinner처럼 생긴 TextView 만들기/ClickListener 추가 본문
[Android/Kotlin]Custom View 만들기/Spinner처럼 생긴 TextView 만들기/ClickListener 추가
minWachya 2022. 3. 20. 16:47아래 UI는 "동네 고영희" 앱 UI입니다!
1, CustomView의 layout 생성
res>layout>custom_spinner_text_view.xml
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/custom_text_view"
style="@style/Widget.AppCompat.EditText"
android:layout_width="match_parent"
android:layout_height="55dp"
android:textSize="16sp"
android:fontFamily="@font/spoqa_han_sans_neo_regular"
android:backgroundTint="@color/beige_E3DECF"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_spinner_drop_down_arrow"
android:layout_marginEnd="26dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2, res>values>attrs.xml(없으면 생성)
내가 필요한 속성은 TextView에서 사용할 hint와
스피너(처럼 생긴 TextView)에서 선택한 값을 보이기 위한 text 속성이었다.
나머지 글씨 크기니 폰트니 하는 속성은 공통적이라 위 xml에서 지정해줌.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--Spinner 처럼 생긴 TextView-->
<declare-styleable name="CustomSpinnerTextView">
<attr name="text" format="reference|string" />
<attr name="hint" format="reference|string" />
</declare-styleable>
</resources>
3, CustomView를 생성할 Class 만들기
package com.example.dongnaegoyang.custom
import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.example.dongnaegoyang.R
// CatAdd2, 3에 쓰이는 Spinner 처럼 생긴 TextView
class CustomSpinnerTextView : ConstraintLayout {
// 커스텀 뷰 안에 들어가는 아이템
lateinit var textView : TextView
// 생성자
constructor(context: Context?) : super(context!!){
init(context)
}
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs){
init(context)
getAttrs(attrs)
}
// 초기화
private fun init(context:Context?) {
val view = LayoutInflater.from(context).inflate(R.layout.custom_spinner_text_view,this,false)
addView(view)
textView = view.findViewById(R.id.custom_text_view)
}
// 속성 가져오기
private fun getAttrs(attrs: AttributeSet?){
val typedArray = context.obtainStyledAttributes(attrs,
R.styleable.CustomSpinnerTextView)
setTypeArray(typedArray)
}
// 속성 사용하기
private fun setTypeArray(typedArray : TypedArray) {
// 텍스트 내용: CustomSpinnerTextView 이름으로 만든 attrs.xml 속성중 text 참조
val text = typedArray.getText(R.styleable.CustomSpinnerTextView_text)
textView.text = text
// 텍스트 힌트: CustomSpinnerTextView 이름으로 만든 attrs.xml 속성중 hint 참조
val hint = typedArray.getText(R.styleable.CustomSpinnerTextView_hint)
textView.hint = hint
typedArray.recycle()
}
}
완성~~~~~^___________________^
4, CustomView 사용하기!
나는 CustomSpinnerTextView를 custom 폴더 안에서 만들어서 class 명 앞에 custom이 붙은 거다!!
내가 만든 속성을 사용하고 싶으면 app:속성명 <이렇게 사용하면 된다.
<com.example.dongnaegoyang.custom.CustomSpinnerTextView
android:id="@+id/foodSpinner"
app:hint="@string/cat_add_food_hint"
android:layout_column="1"
android:layout_row="1"
android:layout_gravity="fill_horizontal"
android:layout_height="55dp"/>
class 안에서 커스텀 속성을 사용하고 싶으면...그냥 view.속성명 <이렇게 접근하면 된다.
요로코롬
binding.foodSpinner.textView.setOnClickListener { foodBottomSheetDialog.show() }
(+4. ClickListener 추가)
클릭 리스너를 위와 같이 추가해줘도 동작은 되지만,,, 다른 방법도 소개하려 한다.
CustomSpinnerTextView,kt
위와 달라진 점은
- View.OnClickListener 상속
- onCustomSTViewClick 함수를 포함한 OnCustomSTViewClickListener 인터페이스 추가
- 위 인터페이스 타입의 변수 myOnCustomSTViewClickListener 추가
- 초기화 시 클릭 리스너 달기
- OnClick 오버라이드
이다.
package com.example.dongnaegoyang.custom
import android.content.Context
import android.content.res.TypedArray
import android.util.AttributeSet
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import com.example.dongnaegoyang.R
// CatAdd2, 3에 쓰이는 Spinner 처럼 생긴 TextView
class CustomSpinnerTextView : ConstraintLayout, View.OnClickListener {
// 커스텀 뷰 안에 들어가는 아이템
lateinit var textView : TextView
// 믈릭 리스너
private var myOnCustomSTViewClickListener: OnCustomSTViewClickListener? = null
// 클릭 리스너를 전달할 함수를 담은 인터페이스
interface OnCustomSTViewClickListener { fun onCustomSTViewClick(view: View?) }
// 전달받은 클릭 리스너 달기
fun setOnCustomSTViewClickListener(mListener: OnCustomSTViewClickListener) {
myOnCustomSTViewClickListener = mListener
}
// 생성자
constructor(context: Context?) : super(context!!){
init(context)
}
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs){
init(context)
getAttrs(attrs)
}
// 초기화
private fun init(context:Context?) {
val view = LayoutInflater.from(context).inflate(R.layout.custom_spinner_text_view,this,false)
addView(view)
textView = view.findViewById(R.id.custom_text_view)
textView.setOnClickListener(this@CustomSpinnerTextView)
}
// 속성 가져오기
private fun getAttrs(attrs: AttributeSet?){
val typedArray = context.obtainStyledAttributes(attrs,
R.styleable.CustomSpinnerTextView)
setTypeArray(typedArray)
}
// 속성 사용하기
private fun setTypeArray(typedArray : TypedArray) {
// 텍스트 내용: CustomSpinnerTextView 이름으로 만든 attrs.xml 속성중 text 참조
val text = typedArray.getText(R.styleable.CustomSpinnerTextView_text)
textView.text = text
// 텍스트 힌트: CustomSpinnerTextView 이름으로 만든 attrs.xml 속성중 hint 참조
val hint = typedArray.getText(R.styleable.CustomSpinnerTextView_hint)
textView.hint = hint
typedArray.recycle()
}
// 클릭 효과 방샐
override fun onClick(v: View?) {
myOnCustomSTViewClickListener!!.onCustomSTViewClick(v)
}
}
아까의 쿨릭 리스너를 적용한 코드가 이렇게 변한다.
binding.genderSpinner.setOnCustomSTViewClickListener(object : CustomSpinnerTextView.OnCustomSTViewClickListener {
override fun onCustomSTViewClick(view: View?) { genderBottomSheetDialog.show() }
})
드뎌드뎌 CstomView를 만들어서 사용해봤다.
내가 만들어야 하는 view는 위와 같았다.
밑줄이 있고 + spinner의 삼각형 부분만 색이 다르고 + hint가 있는 스피너 부분...!!!
그냥 냅다 Spinner로 만들었더니 생긴 문제점
- Spinner에는 hint 속성이 없음
- spinner array를 보여주는 부분을 기존 spinner에서 제공해주는 것을 사용하지 않음
- (BottomSheetDialog로 spinner array를 보여야 했다.)
그래서 그냥 TextView로 만들었더니 생긴 문제점
- TextView에 underline + spinner drop down arrow button 필요
- =>style="@style/Widget.AppCompat.Spinner.Underlined" 사용해서 해결
- Spinner drop down arrow button 색만 변경해야 하는데 "android:backgroundTint="@color/~" 방식을는 underline과 down button 모두의 색을 바꿈
그래서 어떻게 만들까 하다가 어짜피 다른 곳에도 사용되는 View이니 결국 Custom 하게 됐다.
TextView에 underline은
style="@style/Widget.AppCompat.EditText"
이거 써서 해결
drop down arrow button color는 그냥 이미지 사용해서 해결^_______________^
참고
https://leejieun1121.github.io/android/Android-CustomView-%EB%A7%8C%EB%93%A4%EA%B8%B0(kotlin)/
https://gun0912.tistory.com/38
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[Android/Kotlin]음성인식(STT:Speech-To-Text) 만들기 (0) | 2022.04.21 |
---|---|
[Android/Kotlin] 지문인식 만들기 (0) | 2022.04.08 |
[Android/Kotlin]EditText scollbar custom/cursor color (0) | 2022.03.19 |
[Android/Kotlin] TabLayout: unselected tab indicator/미선택된 탭의 이터레이터 색 설정/탭 밑줄/tab underline (0) | 2022.03.19 |
[Android/Kotlin] FragmentContainerView 연습 Code with Joyce (0) | 2022.03.05 |