본문 바로가기

Android/Android Custom View

[XML] AmbientLightView

1 인 개발을 진행했던 앱 '에이펙싱' 의 디자인이 너무 별로여서 새롭게 리뉴얼 중입니다.

UI 를 개선함과 동시에 스토어 정보를 보여주는 기능을 새로이 개발 중에 있는데, 해당 기능의 UI 를 구현하다가 문제가 조금 생겼습니다.

 

스토어의 아이템은 특별 상품들인 Specials 와 일반 상품들인 Shop 으로 분류가 되는데, 각 상품군의 분류가 확실히 되지 않아서 해당 View 의 Elevation Color 를 변경하여 구분하려 했습니다.

 

관련된 속성을 사용하려 했으나, minSDK 와 호환이 되지 않는 이슈가 발생하여, 이를 해결하기 위해 CustomView 를 구현하였습니다.

 

물론 라이브러리를 사용해도 되고, minSDK 를 올려도 되지만, 저는 minSDK 만은 올리지 않겠다는 생각을 갖고 있기 때문에 라이브러리를 조금 찾아보았습니다. carbon 이라는 라이브러리가 존재하는데, 이를 사용하자니 사용하지 않는 기능들까지 너무 많이 추가되는 것이 꺼림칙했습니다.

 

그래서 그냥 직접 하나 만들자 싶어서 빠르게 구현해보았습니다.

 


 

기존의 UI 입니다. 좌측이 Specials 상품군, 우측이 Normal 상품군입니다.

이미지에는 두 View 를 붙여 놓았으나, 실제 UI 는 Specials 상품만 존재하는 Horizontal RecyclerView 가 위에 있고, 

아래에는 Shop 상품만 존재하는 Horizontal RecyclerView 가 있습니다.

그래서 사실 텍스트 색상만 조금 변경해주어도 구분이 되겠지만, 뭔가 더 직관적인 UI 를 구현하고 싶었습니다.

 

 

빠르게 구현해낸 AmbientLightView. 서서히 퍼지는 Ambient Light 를 표현하기 위해 100 번의 연산을 진행합니다.

Alpha value 를 1(0.01) 씩 줄여나가고, 바깥 방향으로 lightLength 의 1/100 씩 위치를 늘려가며 그려냅니다.

 

private fun drawLight(canvas: Canvas) {
    val paint = Paint().apply {
        isAntiAlias = true // 안티앨리어싱
        color = lightColor // 퍼져나가는 빛의 루트 색상
        strokeWidth = lightLength / 100 // 100 번의 연산을 진행하기 때문에 100 으로 나누어 줌
        style = Paint.Style.STROKE
    }

    var calLightLength = lightLength

    for (i in 0 until 100) {
        paint.alpha -= i // 알파값을 줄여나감
        canvas.drawRoundRect(
            calLightLength,
            calLightLength,
            measuredWidth.toFloat() - calLightLength,
            measuredHeight.toFloat() - calLightLength, // 연산마다 계산된 위치에 RoundRect 를 그림
            radius,
            radius,
            paint
        )

        calLightLength -= (lightLength / 100) // 위치 설정을 위한 연산
    }
}

 

 

개선된 UI 는 위와 같습니다. Specials Item 과 Shop Item 의 구분이 확실하게 됩니다.

생각했던 것처럼 잘 나와주어서 만족스럽습니다.