안드로이드 개발하는데 있어서 Vector를 사용하는 것은 너무나 편리합니다.

hdpi, xhdpi, xxhdpi, xxxhdpi등 이미지를 몇개나 만들어야 했었는데,

벡터파일 하나면 되니 소스관리도 편하고,

이미지를 만들어서 주는 디자이너들도 좋아합니다.

sketch같은 프로그램으로 export시켜 사용하면 이보다 더 편리한 것은 없죠.


supportLibrary에서 벡터사용을 지원하기 때문에, 사용하는 방법도 쉬운데요.

아쉽게도 안드로이드 개발을 하면서 항상 만나게 되는 하위버전 호환문제가 있습니다.

경우에 따라서, API21미만에서는 리소스를 못찾아서 nullPointerException을 발생시킬 수 있어요.


그럼 어떻게 벡터그래픽을 사용하고, 

API21미만에서는 어떻게 대응해야 하는지 정리해 보도록 하겠습니다.



1. Vector그래픽 사용 준비


먼저 app레벨의 build.gradle파일에 다음과 같이

vectorDrawable에 대해서 서포트라이브러리를 사용한다고 기술해 주어야 합니다.


vectorDrawables.useSupportLibrary = true




두번째로는 supportLibrary의 버전이 23.2이상인지 확인해 보아야 합니다.

저의 경우는 27.1.1버전을 사용하고 있네요



자 그럼 이제 준비는 되었구요.

이제 벡터이미지를 사용해 보도록 하겠습니다.



2. Vector파일 사용하기


안드로이드 스튜디오의 navigation창에서

res> drawable에서 오른쪽 마우스를 눌러서 아래 이미지와 같이

new> Vector Asset을 해줍니다.




그럼 아래와 같은 화면을 볼 수 있는데요.

Local file을 선택하시면 Sketch같은 프로그램을 통해서 export한 svg파일을 가져올 수 있구요.

Clip Art를 선택하시면 안드로이드 스튜디오에서 제공해주는 기본 벡터파일들을 이용하실 수 있습니다.

(기본 제공해주는 벡터소스들의 퀄리티가 정말 좋습니다.

인터넷에서 구하는 싸구려 소스들보다 훌륭하네요)


저는 그냥 Clip Art에서 제공해주는 화살표를 선택했습니다.



Next를 눌러주면 아래와 같이 파일이 들어와 있는 것을 확인할 수 있네요.




3. XML에서 사용하기


XML에서 사용하기는 더욱 쉽습니다.

android:src가 아니라,

app:srcCompat= 붙여주고 소스위치를 적어주면 됩니다.


app:srcCompat="" 




네, 아래와 같이 화살표가 잘 나오는 것을 볼 수 있습니다.

너무나도 쉽네요.

 



4. Java에서 사용하기


Java에서 사용하는 방법도 매우 간단합니다.

아래와 같이 setImageResource메소드를 사용해주면 간단하게 됩니다.




5. API21이하에서의 호환성 문제


안드로이드가 저렇게 쉽게 끝날리가 없지요?

맞습니다. support라이브러리를 쓴다고 api21이하에서 모든 소스의 동작을 허용하지는 않습니다.


5-1. 문제가 되는 부분


단순히 이미지뷰에서 srcCompat을 이용하는 정도라면,

support라이브러리에서 지원하기 때문에 문제가 없는데요.


하지만 사실 프로젝트를 하다보면,

어떨때는 background를 이미지로 사용하거나, 

체크박스와 같이 xml로 이미지를 선택한 경우와 아닌경우를 두개를 만들어서

사용해야 하는 경우도 있습니다.

그런데, 이럴 때는 api21미만의 kitkat같은 경우 문제를 발생시킵니다.


아직도 갤럭시s3,4등의 스마트폰이 사용되고 있으니,

이 부분에 대해서 고민을 많이 해야 하지요.


이럴때 아래 코드를 Activity에 추가해주면,

이런 문제가 해결될 수 있다고 합니다.

물론, 사용후에 반드시 QA를 해야합니다.

(구글에서 된다고 했으니까 하고 release했다가는, crash리포트를 보게 될테니까요.)


AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);


이 메소드의 주석을 읽어보면 아래와 같은데요.

이 옵션을 true로 함으로써 문제들이 발생할 수 있다고 나와있습니다.

쉽게 말하면, 문제가 될 수 있는 부분이 있는데, 이상 없으면 쓰라고 하는,

"사용할 수 있는지 확인해보고, 사용하세요"라는 느낌의 주석이네요.




API21이상에서는 사용할 필요가 없으므로,

OS버전이 Lollipop미만일 경우에만 사용하도록

아래와 같이 할수도 있습니다.

Application.class에 넣어놓으면 각 화면들을 돌아다니면 코드를 적을 필요는 없겠지요.



실제로 저의 경우 체크박스에 사용하는 벡터를 사용할 경우에는 위의 옵션을 사용해서 해결했구요.


adapter에서 view를 생성해 사용하는 경우나 notification에 들어가는 소스의 경우는 nullPointer익셉션이 생겨서,

다시 png로 소스를 디자이너분에게 요청해서 해결했습니다.

검색해 보면, 이런저런 방법을 찾을수도 있겠지만, 이 방법이 더욱 빠르게 해결됩니다 ;)

(일반적인 서비스앱에서 코드로 이미지를 동적으로 붙이는 경우는 그렇게 많지 않으니까요)



6. 속도 문제


Vector그래픽을 사용하는데 있어서 생각해야 할 부분이 있습니다.

특히나 ViewPager에서 fragment를 사용하는 경우에는 더욱 그러한데요.

Vector이미지를 사용함으로서 리소스 관리에 대한 부담도 덜고 다양한 해상도 대응도 쉬워지는 반면

속도가 느려질 수 있다는 단점이 있습니다.

유저에게 보여지는 이미지 사이즈가 클수록 더욱 그러한데요.


Vector이미지도 결국 처음에는 Bitmap으로 그려져서 GPU에 업로드 되는데요.

사이즈가 클수록 로딩되는 시간도 길어지고 메모리도 많이 차지하게 되어서,

속도 저하를 가져올 수 있습니다.

안드로이드측에서는 200dp사이즈 이하에서,

버튼같이 작은 리소스들에만 사용하기를 권장하고 있습니다.

(그런데 위에서 언급한데로 버튼에 쓰려면 하위호환 문제가 있기는 합니다)


요즘은 Sketch같은 디자인툴들도 벡터그래픽으로 출력하는 것을 지원하기에,

디자이너들도 벡터로 리소스를 주는 것을 선호하지만,

ViewPager나 List처럼 스와이핑해서 화면이 전환되는 경우처럼,

로딩속도가 앱의 품질에 영향을 미치는 경우에

주의를 기울여야 합니다.



7. 정리


vector그래픽이 주는 편안함이 있지만,

srcCompat으로 사용하거나, 단순히 java에서 view소스에 setImageResource해서 사용하는 경우가 아니라면,

예전처럼 png이미지를 여러개 사용해서 하는것이 훨씬 효율적이고 QA부담을 덜어주는 것 같습니다.


물론 google에서 하위호환성을 담보해주는 supportLibrary를 업데이트해주면 더욱 좋겠지만,

벡터를 지원해준지 시간이 흘렀음에도, 특별히 이 부분에 대한 개선이 이루어지지 않는 것으로 보면,

기대하지 않고 있는게 더욱 좋을 것 같습니다.


관련해서 구글의 업데이트가 있으면 이 글을 통해서 업데이트해 드리도록 하겠습니다

+ Recent posts

티스토리 툴바