방명록
- [Android] 커스텀뷰 만들기2023년 10월 04일 22시 38분 31초에 업로드 된 글입니다.작성자: 핀수728x90반응형
커스텀뷰
xml (view)에서의 모듈화는 CustomView로 해결이 가능하다.
이렇게 생긴 버튼이 있다.
<androidx.appcompat.widget.AppCompatButton android:layout_width="0dp" android:layout_height="0dp" android:autoSizeMaxTextSize="20sp" android:autoSizeStepGranularity="1sp" android:autoSizeTextType="uniform" android:background="@drawable/bg_responsive_button" android:gravity="center" android:text="Sign up with Google" android:textAllCaps="false" android:textColor="@color/black" app:layout_constraintEnd_toStartOf="@+id/guideline6" app:layout_constraintHeight_percent="0.06" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline4" />
이런 화면을 만들어야 한다고 할때,
저 버튼 네개를 복붙해서 만들면 되겠지? 라고 생각할 수 있다.
그렇지만 만약 어떤 수정사항이 생긴다면? 네번 수정을 해주어야 한다.
그러다 보면 그 과정에서 생기는 오류나 실수는 아주 자연스러운 수순이 된다. (경험담
이를 방지하고자 style을 사용했지만..좀 더 쌈빡한 방법은 없을까? 라고 생각이 되어질 때 쯤에서야
CustomView를 알게 되었다…….늦었다고 생각할 때가 가장 빠른 법
얼른 알아보자.
만들기
1. xml 작업하기
생성할 커스텀 뷰의 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" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="8dp" android:background="@drawable/bg_responsive_button"> <ImageView android:id="@+id/symbol" android:layout_width="0dp" android:layout_height="50dp" android:padding="4dp" app:layout_constraintHorizontal_weight="1" android:src="@drawable/img_google_logo" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/text" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/text" android:layout_width="0dp" android:layout_height="wrap_content" android:gravity="center" android:text="Sign up with Google" style="@style/JoinText" app:layout_constraintHorizontal_weight="9" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/symbol" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
2. attrs.xml 만들기
커스텀뷰에 들어갈 속성을 정의한다.
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="JoinViaSocialButton"> <attr name="bg" format="reference|integer" /> <attr name="symbol" format="reference|integer" /> <!-- 이 attr은 나중에 app:text="....." 로 쓰일수 있으며 '가나다라' 같은 직접적인 String과 @string/aaaa 같은 reference를 넣어줄 수 있습니다. --> <attr name="text" format="reference|string" /> <attr name="textColor" format="reference|integer" /> </declare-styleable> </resources>
3. CustomView 만들기
1) 생성자
class JoinViaSocialButton : ConstraintLayout { constructor(context: Context): super(context) { initView() } constructor(context: Context, attrs: AttributeSet): super(context, attrs){ initView() getAttrs(attrs) } ... }
2) initView
ViewBinding 기준으로 작성
- 미리 만들어둔 xml 파일을 할당
- 각각의 view 설정
private lateinit var bg: ConstraintLayout private lateinit var symbol: ImageView private lateinit var text: TextView private val binding: JoinViaSocialButtonBinding by lazy { JoinViaSocialButtonBinding.bind( LayoutInflater.from(context).inflate(R.layout.join_via_social_button, this, false) ) } private fun initView(){ addView(binding.root) bg = binding.root symbol = binding.symbol text = binding.text }
3) getAttrs()
attrs.xml 에 선언해둔 속성들을 이용해 각각의 view에 설정
private fun getAttrs(attrs: AttributeSet){ val typedArray = context.obtainStyledAttributes(attrs, R.styleable.JoinViaSocialButton) setTypeArray(typedArray) } private fun setTypeArray(typedArray: TypedArray){ binding.run { val bgId = typedArray.getResourceId(R.styleable.JoinViaSocialButton_bg, R.drawable.bg_responsive_button) bg.setBackgroundResource(bgId) val symbolId = typedArray.getResourceId(R.styleable.JoinViaSocialButton_symbol, R.drawable.img_google_logo) symbol.setImageResource(symbolId) val defColorId = context.resources.getColor(R.color.black, null) val textColor = typedArray.getColor(R.styleable.JoinViaSocialButton_textColor, defColorId) text.setTextColor(textColor) val textString = typedArray.getString(R.styleable.JoinViaSocialButton_text) text.text = textString typedArray.recycle() } }
4) 나머지 코드 작성
fun setBg(resourceId: Int){ bg.setBackgroundResource(resourceId) } fun setSymbol(resourceId: Int) { symbol.setImageResource(resourceId) } fun setTextColor(colorId: Int){ text.setTextColor(colorId) } fun setText(textString: String){ text.text = textString } fun setText(textId: Int){ text.text = context.getText(textId) }
사용하기
<com.pinslog.navermapsample.view.custom.JoinViaSocialButton android:layout_width="0dp" android:layout_height="0dp" app:text="Sign up with Google" app:layout_constraintEnd_toStartOf="@+id/guideline6" app:layout_constraintHeight_percent="0.06" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline4" />
공부하며 작성된 글이라 잘못된 정보가 있을 수 있습니다.
말씀해주시면 수정하겠습니다. 감사합니다.
References
아래 글을 참고하여 작성 되었습니다.
[Android] Custom View로 생산성 높이기
사용성 증가
velog.io
[안드로이드/Android]CustomView를 만들어서 재사용하기
이전 포스팅에서 Style테마를 이용하여 일정한 레이아웃의 속성을 만들고 이를 재사용하는 방법에 대해서 알아 보았습니다.[안드로이드]style테마 활용으로 노가다코딩 줄이는 방법 이 방법보다
gun0912.tistory.com
728x90반응형'Android > Android' 카테고리의 다른 글
[Android] Jetpack Compose 프로젝트 생성 + MainActivity 살펴보기 (0) 2023.10.06 [Android] Thread와 Coroutine (0) 2023.10.05 [Android] Jetpack Compose? true! (0) 2023.09.30 [Android] Room 살펴보기 (0) 2023.09.28 [Android] DataBinding 적용하기 - 03 (0) 2023.09.27 다음글이 없습니다.이전글이 없습니다.댓글