[안드로이드] 원형 이미지 및 배경색 지정

hee09·2022년 1월 24일
0
post-thumbnail

개요

위의 사진과 같이 원모양의 이미지뷰안에 아이콘을 설정하고 색을 지정하는 코드를 작성하는데 많은 삽질을 하다가 방법을 발견하여 글을 작성하게 되었습니다.


접근 1 - 라이브러리 사용

CircleImageView라는 라이브러리를 사용할 수 있습니다. CircleImageView 라이브러리는 XML 파일에 CircleImageView라는 뷰를 추가한 후 여러가지 속성을 통해 원 모양의 이미지를 만들 수 있는 라이브러리입니다.

의존성 추가

작성일 기준 github에 나와있는 버전을 작성하였습니다.

dependencies {
    ...
    implementation 'de.hdodenhof:circleimageview:3.1.0'
}

기본적인 사용방법

<de.hdodenhof.circleimageview.CircleImageView
    android:id="@+id/item_category_image"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:src="@drawable/baseline_restaurant_menu_white_20"
    app:civ_border_color="@color/white"
    app:civ_border_overlay="true"
    app:civ_border_width="5dp"
    app:civ_circle_background_color="@color/black"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

XML에 위와 같은 뷰를 추가하면 되고 속성은 아래와 같습니다.

  • src
    ImageView와 마찬가지로 표시할 이미지 resource 파일입니다.

  • civ_border_overlay
    CircleImageView의 테두리가 이미지와 겹칠 것인지 설정하는 속성입니다. default는 false로 false로 설정하면 이미지 바깥쪽에 테두리를 그리고, true로 설정하면 이미지와 겹치게 테두리를 그립니다.

  • civ_border_width
    테두리의 굵기를 나타내는 속성입니다.

  • civ_border_color
    테두리의 색상을 나타내는 속성입니다.

  • civ_circle_background_color
    백그라운드 색상을 지정하는 속성으로 src(이미지)를 제외한 나머지 배경색을 지정합니다.


동적으로 이미지 배경 지정

위의 방식은 XML에서 정적으로 배경을 지정하고 사용하는 방법입니다. 이와는 다르게 저는 동적으로 이미지마다 다른 배경색을 지정해야 하기에 RecyclerView 코드에서 아래와 같이 작성하였습니다.

XML

<de.hdodenhof.circleimageview.CircleImageView
    android:id="@+id/item_category_image"
    android:layout_width="45dp"
    android:layout_height="45dp"
    app:civ_border_width="5dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

우선 xml에서는 위와 같이 설정합니다. 배경색이나 src(이미지) 그리고 테두리와 같은 색상은 코드상에서 지정하기 위해 속성으로 작성하지 않았습니다. 다만 이미지와 배경이 붙지 않기 위해서 border 속성을 사용하였습니다. 차이점을 보자면 아래와 같습니다.


border 속성 지정border 속성 지정 X

코드

// 이미지 획득
val resId = context.resources.getIdentifier(typeEntity.typeImageName,
    "drawable", context.packageName)

// CircleImageView 속성 지정
view.itemCategoryImage.apply {
    // 이미지 설정
    setImageResource(resId)
    // 테두리색 지정
    borderColor = Color.parseColor(typeEntity.typeColor)
    // 배경색 지정
    // 인자는 헥스 색상 코드에 해당
    circleBackgroundColor = Color.parseColor(typeEntity.typeColor)
}

코드는 위와 같이 작성하였습니다.

  1. 우선 이미지를 획득하기 위해서 resources.getIdentifier 메소드를 사용합니다. getIdentifier는 주어진 resource name에 해당하는 resouece ID를 반환하는 메소드로 매개변수는 리소스 이름(이미지 이름을 지정), 리소스 타입, package 이름입니다.

  2. 그 후 CircleImageView의 속성들을 사용하여 원하는 이미지를 만듭니다. setImageResource를 사용해 이미지를 지정, borderColor(테두리색)과 circleBackgroundColor(배경색)은 같은 색을 지정합니다. 이와 같이 작성하면 위와 같이 원 모양의 이미지뷰안에 아이콘이 자리잡은 뷰를 작성할 수 있습니다.


접근 2 - 라이브러리 사용 X

라이브러리를 사용하지 않고 ImageView를 사용하여 원 모양의 이미지를 작성할 수 있습니다. 우선 원 모양을 지정하기 위한 Drawable XML 파일을 하나 작성합니다.

shape.xml 파일

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
</shape>

shape 태그로 시작하여 shape라는 속성으로 oval(원)을 지정합니다. 이외에 테두리(stroke), 배경(solod), 크기(size)등을 지정할 수 있지만, CircleImageView와 같이 동적으로 색을 지정하기에 작성하지 않았습니다.

xml

<ImageView
    android:id="@+id/item_category_image"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:background="@drawable/shape"
    android:padding="10dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

ImageView의 background로 위에서 만든 drawable 파일을 지정하고, padding 속성을 주어서 이미지가 테두리와 떨어지게끔 작성하였습니다. padding 속성을 지정하지 않는다면 CircleImageView에서 테두리를 지정하지 않는 것과 마찬가지의 상태가 됩니다.

코드

// 이미지 획득
val resId = context.resources.getIdentifier(typeEntity.typeImageName,
    "drawable", context.packageName)

view.itemCategoryImage.apply {
    // 이미지 적용
    setImageResource(resId)
}

// GradientDrawable 객체 획득
val bgShape = view.itemCategoryImage.background as GradientDrawable
// GradientDrawable 색 지정
// 인자는 헥스 색상 코드에 해당
bgShape.setColor(Color.parseColor(typeEntity.typeColor))

코드는 위와 같이 작성하였고 이미지를 획득하는 부분은 CircleImageVIew와 똑같습니다. 차이점은 배경색을 지정하는 코드입니다. 다만 ImageView의 setBackgroundColor 메소드를 통해 배경색을 지정하면 XML 파일에서 background 속성으로 지정한 oval 모양으로 배경색이 칠해지는 것이 아닌 사각형 모양으로 배경색이 칠해집니다. 이를 위해 GradientDrawable 클래스를 사용해야 하는데, GradientDrawable 클래스는 아래와 같습니다.

button과 background 등에 대한 색상 그라데이션을 그릴 수 있으며, XML 파일에서 <shape>라는 요소로 정의된다고 나와있습니다. <shape> 요소에 해당하는 Shape Drawable은 색상 및 그라데이션 등 기하하적 모양을 정의하는 XML 파일로, 이에 접근하려면 GradientDrawable을 사용하면 됩니다. 즉, 일반적으로 이미지뷰에 backgroundColor를 지정하는 것은 이미지뷰 자체의 백그라운드를 지정하는 것이지만, ImageView의 background를 GradientDrawable로 캐스팅하게 되면 기하하적 모양(예제에서는 oval에 해당)을 획득하는 것입니다. 따라서 이를 이용해 색을 지정하면 자신이 설정한 모양에 배경색을 칠할 수 있습니다.


참고
Shape Drawable + 동적으로 색 변경해보기
ImageView round corner, radius 주기 / 이미지뷰 코너 둥글게 하기

틀린 부분은 댓글로 남겨주시면 수정하겠습니다..!!

profile
되새기기 위해 기록

0개의 댓글