버튼 수집상

[안드로이드] TextView 원하는 글자만 남기고 말줄임표 보여주기 Custom Ellipsis 본문

TIL - 안드로이드

[안드로이드] TextView 원하는 글자만 남기고 말줄임표 보여주기 Custom Ellipsis

cocokaribou 2023. 12. 7. 15:17

배경

텍스트가 길어졌을 때 말줄임표와 함께 & more가 노출되게 해달라는 요구사항이 있었다.

brand1, brand2, brand3, brand4

❌ brand1, brand2, b…
✅ brand1, br… & more

 

TextView의 텍스트 길이가 화면 너비를 넘어갈 때 처리를 위해 ellipsize 옵션이 제공된다.

ellipsize 예시 "aaabbbcccddd"
none aaabbbccc
start …bcccddd
middle aaa…cddd
end aaabbbc…
marquee 오른쪽에서 왼쪽으로 흐르는 효과

단, 아래 조건 필요
textView.isSelected = true
textView.isSingleLine=true
(singleLine대신 maxLines=1로 잡는 건 안 됨)

 

android:ellipsize="middle"을 넣으면 중간을 생략하고 마지막 단어를 보여주지만, 원하는 모양으로 줄일 수 없었다.

❌ brand1, …d4 & more
✅ brand1, br… & more

 

화면 너비에 쏙 들어오는 글자수를 계산해서 "… & more"를 붙여줬다.

 

TextView가 잘렸는지 체크하는 함수

fun TextView.isEllipsized(lineCount: Int = 1) : Boolean {
    layout ?: return false
    return layout.getEllipsisCount(lineCount - 1) > 0
}

 

TextView 예시

<TextView
    android:id="@+id/brand"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:textSize="14dp"
    android:maxLines="1"
    android:ellipsize="end"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    />

kotlin 코드

// banner 데이터

var brandName = banner.brandNm
val moreThan2Brands = banner.brandCnt > 2
val suffix = " & more"

// brandCnt > 2 일 때 "& more" 추가
// 화면 너비 넓을 때 : "브랜드명1, 브랜드명2 & more"
if (moreThan2Brands) brandName += suffix
binding.brand.text = brandName

binding.brand.post {
    // 화면 너비 좁을 때 : "브랜드명1, 브랜… & more"
    if (moreThan2Brands && binding.brand.isEllipsized()) {
        val endIndex = binding.brand.layout.getEllipsisStart(0) - suffix.length - 2
        if (endIndex > 0) {
            val shortenedText = banner.brandNm?.substring(0, endIndex)
            binding.brand.text = "$shortenedText…$suffix"
        }
    }
}

말줄임표는 온점 세개가 아닌 별도의 기호를 썼다.

…(U+2026)

 

getEllipsisStart(0)는 말줄임표 직전의 문자열 인덱스를 가져온다

[0] [1] [2] [3] [4] [5] [6]
b r a n d 1

 

위의 경우 5를 리턴하게 된다.

 

 

post 블럭으로 UI 스레드에 접근하는 이유:

최초로 화면에 그려졌을 때 TextView 정보를 가져와야하기 때문이다.

 

 

추신

ellipsize 라는 동사는 사전에 없는 말이었다.

말줄임표라는 뜻의 ellipsis는 있다.

 

728x90