- Published on
- ·7 min read
Color Picker(ambilwarna) 라이브러리 사용하여 색상 변경(안드로이드)
개요
sosone 프로젝트의 스마트 탁상 시계(안드로이드)에 배경색과 텍스트색을 사용자가 직접 지정하는 기능을 추가하였습니다.
색상 선택은 Android Color Picker(ambilwarna) 라이브러리를 사용했습니다.
서비스 바로가기
화면 미리보기
동작 화면은 아래 이미지와 같습니다.
이미지 좌측의 색상 버튼을 클릭하면, 우측의 색상 선택 Dialog가 표시됩니다.
작업 간략 소개
build.gradle(Module)에 라이브러리 추가
implementation 'com.github.yukuku:ambilwarna:2.0.1'
Layout 부분
- 색상 버튼 추가
Kotlin 코드 부분
- 버튼 클릭 시 색상 선택 Dialog 호출 및 선택 시 Listener 설정
layout
fragment_setting.xml
- 색상 버튼을 표시하는 설정 레이아웃 중 색상 선택 버튼 부분입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout ... 생략 ...>
<!-- 생략 -->
<LinearLayout
android:id="@+id/view_custom_colors"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone"
android:baselineAligned="false"
>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginEnd="2dp"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/background_color" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_custom_background_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:backgroundTint="@color/default_background_color"
app:strokeColor="@color/teal_700"
app:strokeWidth="4dp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:orientation="vertical">
<com.google.android.material.textview.MaterialTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/text_color" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_custom_text_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:backgroundTint="@color/default_text_color"
app:strokeColor="@color/teal_700"
app:strokeWidth="4dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Kotlin Source (Fragment)
SettingFragment.kt
코드 내 주석을 참고해 주세요.
package kr.sosone.clock
import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import kr.sosone.clock.common.EnumFont
import kr.sosone.clock.common.Util
import kr.sosone.clock.common.Util.Companion.marginPixel
import kr.sosone.clock.common.Util.Companion.presetSize
import kr.sosone.clock.databinding.FragmentSettingBinding
import kr.sosone.clock.viewmodels.ClockViewModel
import kr.sosone.clock.viewmodels.ClockViewModelFactory
import yuku.ambilwarna.AmbilWarnaDialog
class SettingFragment : Fragment() {
private var _binding : FragmentSettingBinding? = null
private val binding get() = _binding!!
// 설정한 Data는 viewMode에서 관리
private val viewModel: ClockViewModel by activityViewModels{
ClockViewModelFactory(
(activity?.application as ClockApplication).database.settingDao()
)
}
// ...생략...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 버튼 색상 지정
// 저장된 색상은 String이므로 Color.parseColor 이용하여 Int로 변경
binding.btnCustomBackgroundColor.setBackgroundColor(Color.parseColor(viewModel.customBackgroundColor.value))
binding.btnCustomTextColor.setBackgroundColor(Color.parseColor(viewModel.customTextColor.value))
// 색상 버튼 클릭 시 loadColorPicker 함수 호출
binding.btnCustomBackgroundColor.setOnClickListener {
loadColorPicker(viewModel.customBackgroundColor.value ?: Util.defaultBackgroundColor, true)
}
// 색상 버튼 클릭 시 loadColorPicker 함수 호출
binding.btnCustomTextColor.setOnClickListener {
loadColorPicker(viewModel.customTextColor.value ?: Util.defaultTextColor, false)
}
}
// Color Picker 라이브러리가 호출 되는 부분
private fun loadColorPicker(defaultColor: String, isBackgroundColor: Boolean){
val color = Color.parseColor(defaultColor)
AmbilWarnaDialog(requireActivity(), color,
object : AmbilWarnaDialog.OnAmbilWarnaListener {
override fun onCancel(dialog: AmbilWarnaDialog?) {
}
// 색상 변경 시 처리 내용
override fun onOk(dialog: AmbilWarnaDialog?, color: Int) {
// Int형인 color를 String형인 ViewModel에 저장하기 위한 변환 코드
val hexColor = String.format("#%06X", 0xFFFFFF and color)
if(isBackgroundColor){
viewModel.changeCustomBackgroundColor(hexColor)
binding.btnCustomBackgroundColor.setBackgroundColor(color)
}else{
viewModel.changeCustomTextColor(hexColor)
binding.btnCustomTextColor.setBackgroundColor(color)
}
}
}).show()
}
}
라이브러리에 대한 더 자세한 내용은 yukuku/ambilwarna github을 참고하세요.
덧붙이는 내용
어떤 라이브러리를 사용할까 검색을 하고 처음에는 ColorPickerView를 사용하기로 했습니다.
현재(2023)까지도 업데이트가 활발한 것으로 보이고, 디자인도 좋고, 사용법도 간단합니다.
하지만 회전 시 Dialog 크기가 맞지 않아 포기했습니다. ㅠㅠ
커스텀이 가능하시거나, 회전이 필요 없다면 해당 라이브러리도 좋아 보입니다.
(제가 사용한 AmbilWarna 라이브러리는 최종 업데이트가 꽤 오래된 것으로 보입니다.
하지만 저의 프로젝트 버전인 compileSdk 33, targetSdk 33 버전에도 잘 동작했습니다.
디자인과 업데이트는 조금 별로이긴 하지만, 기능상의 문제는 없었기 때문에 선택했습니다.)
태그와 연관된 글
2023. 12. 17.
데이터 양이 많아지면서 발생한 React Native 앱 성능 문제 개선하기2023. 11. 21.
애드몹(AdMob) GDPR 적용 - React Native(안드로이드)2023. 11. 20.
애드몹(AdMob) GDPR 적용 - 안드로이드2023. 11. 16.
진행률을 표시할 Progress Bar(Circle) 만들기 - React Native2023. 07. 23.
Spinner 이용하여 Dropdown(select box) 구현(안드로이드)