코틀린 앱을 개발하다가 모서리가 둥근 직사각형 또는 원 안에 아이콘을 넣고 싶었다.
맨 처음에 수작업으로 xml 파일을 drawable 폴더에 넣어서 시도했으나, 잘 되지 않아(...)
편하게 작업하고자 라이브러리를 찾아서 해결했다.
코틀린 관련하여 자료찾기가 생각보다 힘들었기도 하고, 첫 코틀린 앱이기에 정리해두고자 기록한다.
CircleImageView 공식 사이트는 깃허브를 참고하면 된다. 사용 전에 읽어보자.
dependencies {
implementation ("de.hdodenhof:circleimageview:3.1.0")
}
우선 build.gradle.kts 파일의 dependencies 에 추가하고 Sync now 로 적용시켜준다.
깃허브에 3.1.0버전까지 업데이트 되었다고 안내되어있다. 글 작성일자 기준 제일 최근 버전이다.
xml 파일에서 사용하려면 아래처럼 작성하면 된다.
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profile_image"
android:layout_width="96dp"
android:layout_height="96dp"
android:tint="@color/white"
android:src="@drawable/profile"
app:civ_border_width="2dp"
app:civ_border_color="#FF000000"
app:civ_border_overlay="true"
app:civ_circle_background_color="@color/green_700" />
src
: 이미지를 불러온다.civ_circle_background_color
: 이미지의 배경색을 지정한다.civ_border_width
: 테두리 두께를 지정한다.civ_border_color
: 테두리 색깔을 지정한다.civ_border_overlay
: 테두리를 이미지와 겹칠 건지 설정한다. true이면 테두리가 이미지 안쪽부터 그려지고, false이면 테두리가 이미지 바깥에서 그려진다.아이콘 색깔을 바꾸고 싶으면 다른 view 요소들 처럼 tint 로 색깔을 변경해주면 된다.
CircleImageView의 특징은 설정한 width, height에 딱 맞게 이미지를 원 모양으로 만들어준다는 것이다. 둥근 칸 안에 넣고 싶은게 배경이 투명한 아이콘이라면 조금 문제가 생긴다..
CircleImageView에 넣고자 하는 별 모양 아이콘이다. 보다시피 이미지 전체에서 아이콘 밖으로 남는 여백보다 아이콘이 차지하는 부분이 크다. 심지어 여기서 둥글게 잘리니까 거의 여백이 없게 원 안에 별 아이콘이 가득 차게 된다. 애초에 여백이 좀 있는 아이콘을 구하면 되지만 그게 쉽지는 않다.(여백 없이 꽉 찬 아이콘이라면 원 안에 들어가면 무조건 잘리게 되므로 주의)
그런데, 난 이런 모습이 싫다! 너무 답답해보인다. 아이콘 밖으로 여백이 좀 있었으면 좋겠다.
css라면 그냥 padding을 줄텐데 여기선 그런 방법이 통하지않는다. 그래서 이미지 밖의 테두리로 꼼수를 쓴다.
아래 두 사진은 배경색과 똑같은 색으로 테두리를 준 경우이고, civ_border_overlay
속성만 다르다.
civ_border_overlay 속성이 true
일 때 : 이미지 안으로 테두리가 생겼다.
civ_border_overlay 속성이 false
일 때 : 이미지 밖으로 테두리가 생겨 마치 아이콘 밖으로 여백이 더 생긴 것 처럼 보인다.
이와 같은 방법으로 CircleImageView에 아이콘을 넣었다.
위에 설명한 xml 코드로 충분히 설정 가능하지만 나는 카테고리에 따라 배경색과, 아이콘이 다르길 원했기 때문에 코틀린 코드로 작성해야했다.
작성한 코드는 아래와 같다.
when(todolist.category){
"식사" -> {
categoryImg?.apply {
setCircleBackgroundColorResource(R.color.mealColor)
setImageResource(R.drawable.mealicon)
borderColor = ContextCompat.getColor(context, R.color.mealColor)
}
}
"공부" -> {
categoryImg?.apply{
setCircleBackgroundColorResource(R.color.studyColor)
setImageResource(R.drawable.editpen)
borderColor = ContextCompat.getColor(context, R.color.studyColor)
}
}
"운동" -> {
categoryImg?.apply {
setCircleBackgroundColorResource(R.color.workoutColor)
setImageResource(R.drawable.exerciseicon)
borderColor = ContextCompat.getColor(context, R.color.workoutColor)
}
}
"수면" -> {
categoryImg?.apply {
setCircleBackgroundColorResource(R.color.sleepColor)
setImageResource(R.drawable.bedtimeicon)
borderColor = ContextCompat.getColor(context, R.color.sleepColor)
}
}
"기타" -> {
categoryImg?.apply {
setCircleBackgroundColorResource(R.color.etcColor)
setImageResource(R.drawable.etcicon)
borderColor = ContextCompat.getColor(context, R.color.etcColor)
}
}
}
기본적으로 코틀린에서 사용가능한 set...() 메서드들을 사용해도 된다.
setCircleBackgroundColorResource(R.color...)
: 배경색을 바꾼다.
setImageResource(R.drawable...)
: 띄울 이미지를 바꾼다.
setColorFilter(ContextCompat.getColor(context, R.color...))
: 아이콘 색을 바꾼다.
CircleImageView에서 제공하는 변수명들을 사용해서 설정해도 된다.
circleBackgroundColor = ContextCompat.getColor(context, R.color.mealColor)
: 배경색을 바꾼다.
borderColor = ContextCompat.getColor(context, R.color...)
: 테두리 색을 바꾼다.
isBorderOverlay = true / false
: border_overlay 설정을 바꾼다.
위의 코드를 적용한 아이콘이다. 1번 아이콘 원본의 여백이 부족해서 원 안에 들어가니까 잘리긴 하는데 아이콘을 바꾸면 되는 문제다.