안드로이드를 개발하다 보면 아이콘에 색깔을 넣는 경우가 많이 생긴다. 관련 키워드로 검색을 해보면 ColorFilter와 Tint와 관련해서 많은 자료가 나온다.
이번 포스팅에서는 실제로 내가 겪은 문제점을 공유하며 ColorFilter와 Tint의 차이점을 정리해보려고 한다.
내가 오늘 겪은 문제점은 ColorFilter로 값을 지정해줬음에도 색깔이 변경되지 않는 문제였다. 며칠 전에 발견했던 문제였는데 귀찮아서 제대로 찾아보지 않았다가 오늘 자료 조사를 통해 알게 되어서 포스팅을 하게 되었다.
예시를 통해 알아보자. 우선 간단한 이미지 리소스를 먼저 지정해준 뒤, 레이아웃에 설정해주자.
<?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"
tools:context=".MainActivity">
<ImageView
android:id="@+id/image_view"
android:layout_width="50dp"
android:layout_height="50dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:src="@drawable/ic_baseline_directions_walk_24"/>
</androidx.constraintlayout.widget.ConstraintLayout>
ImageView에 색깔을 넣는 방식은 ColorFilter를 설정해주는 방법과 Tint 값을 설정해주는 방법이 있다.
image_view.setColorFilter(Color.parseColor("#55ff0000"))
image_view.imageTintList = ColorStateList.valueOf(Color.parseColor("#55ff0000"))
우선 ColorFilter를 사용해 Activity에서 동적으로 ImageView의 색깔을 바꿔보자. 정상적으로 지정해준 분홍색으로 바뀌는 것을 확인할 수 있다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view.setColorFilter(Color.parseColor("#55ff0000"))
}
}
다음은 tint 값을 변경해서 색깔을 변경해주자. 역시 마찬가지로 정상적으로 바뀌는 것을 확인할 수 있다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view.imageTintList = ColorStateList.valueOf(Color.parseColor("#55ff0000"))
}
}
그렇다면 ColorFilter와 Tint 값을 동시에 설정해주면 어떤 색으로 나오게 될까? ColorFilter로는 분홍색을, Tint로는 검은색을 설정해준다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view.setColorFilter(Color.parseColor("#55ff0000"))
image_view.imageTintList = ColorStateList.valueOf(Color.parseColor("#00000000"))
}
}
분명 Tint 값보다 ColorFilter 값을 먼저 지정해줬음에도 불구하고, 분홍색으로 나오게 된다. 혹시나 해서 위아래의 코드를 바꿔서 시도해봤지만 역시 같은 결과를 얻을 수 있었다.
이를 통해서 색깔을 지정해줄 때 Tint 값보다 ColorFilter 값의 우선순위가 높다는 것을 알 수 있다. (실험에 의한 결과를 바탕으로 추측한 것일 뿐이니 틀린 내용이 있다면 댓글 부탁드립니다.)
그럼 여기서 리소스 파일의 fillColor 값을 검은색으로 변경해보자.
아까와 마찬가지로 Activity에서 동적으로 ColorFilter를 적용해 이미지의 색깔을 변경해보자.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view.setColorFilter(Color.parseColor("#55ff0000"))
}
}
같은 색을 지정해줬지만, 아까와는 다르게 자주색이 입혀지는 것을 볼 수 있다. 이번에는 Tint를 설정해서 색깔을 바꿔보자.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view.imageTintList = ColorStateList.valueOf(Color.parseColor("#55ff0000"))
}
}
ColorFilter와는 다르게 Tint에서는 처음과 같은 분홍색이 나오게 된다. 이러한 현상은 ColorFilter의 특성 때문에 나오게 된다.
ColorFilter에는 여러 가지 Mode가 있다. Mode에 따라서 색을 입힐 때 어떤 방식으로 입혀질지가 정해지게 된다.
위의 예시에서는 색을 일부러 #55ff0000으로 지정해서 반투명하게 만들었다. 따라서 ColorFilter가 적용될 때 위의 그림에서 Partially Transparent 아래의 16가지 모드 중 하나로 지정되게 된다.
@RemotableViewMethod
public final void setColorFilter(int color) {
setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
예시에서는 Mode를 따로 지정해주지 않았기 때문에 기본 값인 src-atop가 적용됐다. 따라서 기본 색인 검은색 위로 반투명한 빨간색이 적용돼서 자주색처럼 보이게 된 것이다. 처음 예시처럼 분홍색을 ImageView에 입히고 싶다면 src-in mode를 사용하면 된다.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
image_view.setColorFilter(Color.parseColor("#55ff0000"), PorterDuff.Mode.SRC_IN)
}
}
ColorFilter의 Mode를 적절히 활용하면 아래와 같이 사진에 색깔을 입히는 것도 가능해진다.
'Android' 카테고리의 다른 글
[Android] CollapsingToolbarLayout 응용하기 - Google Calendar App 클론 코딩 (0) | 2020.09.19 |
---|---|
[Android] ViewTreeObserver란? - View가 그려지는 시점 알아내기 (0) | 2020.09.19 |
[Android] RxKotlin과 Retrofit2를 사용해 Github api 정보 가져오기 (1) | 2020.08.30 |
[Android] Glide 라이브러리 사용하기 (2) | 2020.05.31 |
[Android] 룸(Room) 지속성 라이브러리 (0) | 2020.05.30 |