카테고리 없음

[Android] Expandable TextView

Jun.LEE 2024. 4. 4. 23:09

Expandable TextView를 만들어보려고 한다.

깃허브에 한 프로젝트를 참고하여 만들었다.

 

GitHub - TheCodeYard/EllipsizedTextView: A simple TextView with a simple task: support custom ellipsis.

A simple TextView with a simple task: support custom ellipsis. - TheCodeYard/EllipsizedTextView

github.com

 

기본적으로 TextView에 clickListener를 주어 접거나 피는 행위를 할 예정이다. 

그리고 기존 "..." 으로 설정된 ellipsis를 "... more"로 변경하려고 한다.

 

아주 가벼운 마음으로 시작한 일이었지만

예상 외로 setEllipsisString 함수는 존재하지 않았다.

 

기본적으로 TextView는 String을 UI에 그려준다. 

내가 하고 싶은말은 String Array를 다루는 것이 아니라는 것이다.

 

String의 크기가 커져서 UI에서 줄넘김이 발생하더라도

TextView에서 각 줄에 대한 정보를 얻을 수 없다.

 

TextView에서 받은 String은 cpp Native Layer의 Minikin에 의해서 

TextView의 크기와 각 글자의 크기의 정보를 통해 줄넘김하여 canvas에 그리게 된다.

 

그러므로 5줄로 내용을 제한해주려고 한다면 5줄을 직렬화한 길이를 구하고

텍스트들이 차지하는 크기를 비교해 적절한 index에서 끊어주어야 하는 것이다.

 

class DescriptionTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
): AppCompatTextView(context, attrs, defStyleAttr) {

	/** 생략 */
    
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        
        val availableScreenWidth =
            measuredWidth - compoundPaddingLeft.toFloat() - compoundPaddingRight.toFloat()
        var availableTextWidth = availableScreenWidth * maxLines
        var ellipsizedText = TextUtils.ellipsize(text, paint, availableTextWidth, ellipsize)
    }
}

 

TextView의 Child Class를 하나 만들어 주고 크기를 측정하는 onMeasure함수를 override하고 있다.

 

위에서 말한것 처럼 textview가 차지한 너비를 구하고 maxLines을 곱연산 해주는 것으로

텍스트 길이의 최대치를 정해주었다.

 

다행스럽게도 TextUtils에 너비를 통해 ellipsize를 진행하는 함수가 존재한다.

이후에는 ellipsis가 "..."로 설정되어 있기 때문에 "...more"로 바꾸어 주면 되겠다.