본문 바로가기
기타/세미나

if kakao 2020 - 에디터 프로젝트와 Text Span

by 헤콩 2020. 11. 19.
반응형
이 게시물에서는 if kakao 2020 1일차에 열린 Android 관련 세션 영상 중 에디터 프로젝트와 Text Span 이라는 세션을 정리해보려 합니다.
어디까지나 제가 세션영상을 보며 주관적으로 정리한 내용이기 때문에 부족한 점이 있을 수 있습니다.

이번 세션은 if kakao 2020에서 Young님의 에디터 프로젝트를 진행하면서 적용된 Span 기능이라는 세션 입니다. 평소 코드 상에서는 다뤄보지 않았던 효과 속성이어서 흥미로웠고 보면서 잘 모르는 내용도 있긴 했지만, 에디터 기능에서 많이 사용되는 span 기능에 대해 엿볼 수 있었던 시간이었습니다.

 

에디터 프로젝트와 Text Span

✏️ Android Text Span

👉 보통 TextView 속성으로 꾸미게 되면 View 전체에 적용이 됩니다.

👉 하지만 아래 예시처럼 Span을 이용하면 XML의 설정을 기반으로 원하는 부분만 꾸밀 수 있습니다.

 

val spannableString = SpannableString("Hello World!")
spannableString.setSpan(
    ForegroundColorSpan(Color.BLUE),
    6,
    11,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 
)
textView.text = spannableString

 

 

/* 위 코드에 아래 코드를 추가하면 기울기를 추가할 수 있습니다 */
spannableString.setSpan(
    StyleSpan(ITALIC),
    6,
    11,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)

 

 

✏️ 플랫폼 별 텍스트 효과 적용 차이

👉 Web는 태그 중심으로 적용합니다.

      bold효과를 0에서 11까지, color효과를 6에서 11까지와 11에서 16까지 줍니다.
👉 Android는 효과 중심으로 적용합니다.

      Bold효과를 0에서 11까지, color효과를 6에서 16까지 줍니다.
👉 iOS는 글자 중심으로 적용합니다.

      Bold효과를 0에서 6까지, Bold+color 효과를 6에서 11까지, color효과를 11에서 16까지 줍니다.

 

 

✏️ SpanClass들의 차이

 

 

✏️EditText Span의 확장

SPAN_EXCLUSIVE_EXCLUSIVE
SPAN_EXCLUSIVE_INCLUSIVE

👉속성 이름에 EXCLUSIVE가 앞에 있으면 시작지점에 적용되지 않고, 뒤에 있으면 끝 지점에 적용되지 않습니다.

👉이와 반면에 INCLUSIVE가 앞에 있으면 시작 지점에 적용이 되고, 뒤에 있으면 끝 지점에 적용이 됩니다.
👉따라서 아래와 같은 4가지 확장 키워드를 활용할 수 있습니다.

        1. SPAN_EXCLUSIVE_EXCLUSIVE
        2. SPAN_EXCLUSIVE_INCLUSIVE
        3. SPAN_INCLUSIVE_EXCLUSIVE
        4. SPAN_INCLUSIVE_INCLUSIVE

 

 

✏️이미 적용된 Span을 꺼내서 삭제하기

👉 글자의 부분만 속성을 얻어와서 삭제한다고 해도 그 삭제한 효과는 전체에 적용이 됩니다. 즉, under line이 3~10자리에 적용이 되어 있을 때, 3~6자리의 span 속성을 가져와서 3~6에 적용되어 있는 under line 속성을 지우면, 3~10자리에 적용된 under line 효과 자체가 삭제됩니다.

 

val spans = spannableString.getSpans(7, 9, UnderlineSpan::class.java)
val underLineSpan = spans[0]
spannableString.removeSpan(underLineSpan)

textView.setText(spannableString)

 

만약 아래처럼 Any로 받을 경우, 모든 종류의 span을 얻어올 수 있습니다.

val spans = spannableString.getSpans(6, 8, Any::class.java)

 

👉하지만 에디터는 사용자가 지우고 싶은 범위만 지울 수 있어야 하기 때문에, 해당 범위에 적용된 span을 가져온 뒤 설정된 영역만 제외하고 다시 지정하도록 하여 해결해야합니다.

 

 

val spans = spannableString.getSpans(7, 9, UnderlineSpan::class.java)
val underLineSpan = spans[0]
var rangeStart = spannableString.getSpanStart(underLineSpan)
val rangeEnd = spannableString.getSpanEnd(underLineSpan)

if (rangeStart < 9) rangeStart = 9
spannableString.removeSpan(underLineSpan)
spannableString.setSpan(
    UnderlineSpan(),
    rangeStart,
    rangeEnd,
    Spannable.SPAN_INCLUSIVE_INCLUSIVE
)

textView.setText(spannableString)

 

❓❓❓

이건 저의 개인적인 생각인데, 코드를 살펴보다보니 if (rangeStart < 9) 부분이 조금 불안정한 것 같습니다.

이 예제에만 해당되는 조건인 것 같고, 만약 under line의 시작부분이 7보다 더 앞선 경우와 under line의 끝 부분이 9보다 큰 경우를 따져봐야할 것 같습니다.

그렇게 된다면, rangeStart가 7보다 작을 경우 rangeStart부터 7까지에도 under line을 재적용 해야하고, rangeEnd가 9보다 클 경우 9부터 rangeEnd까지 under line을 재적용 해야할 것 같습니다.

(물론 개인적인 생각이라 틀릴 수도 있습니다)

 

 

 

🖍 이 외 Span으로 할 수 있는 것들

⭐️Image Span

     👉텍스트 사이에 이미지를 넣을 수 있습니다.
     👉ImageView를 추가하지 않고 이미지를 삽입할 수 있습니다.

 

 

val spannableString = SpannableString("안드로이드 이미지 스팬입니다.")
spannableString.setSpan(
    ImageSpan(this, R.drawable.design_draw),
    6,
    12,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)

textView.setText(spannableString)

 

 

⭐️Clickable Span

     👉텍스트 특정 영역에 클릭 이벤트를 지정할 수 있습니다.
     👉URLSpan도 이 클래스를 상속합니다.

     👉object로 구현하지 않으면 click event가 적용되지 않습니다.

 

 

val spannableString = SpannableString("안드로이드 클릭 스팬입니다.")
spannableString.setSpan(
    object ClickableSpan() {
        override fun onClick(view: View) {
            showToast("Click!!")
        }
    },
    6,
    11,
    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)

textView.setText(spannableString)

 

 

 

 

 

 

 

 

 

if(kakao)2020

오늘도 카카오는 일상을 바꾸는 중

if.kakao.com

 

반응형

'기타 > 세미나' 카테고리의 다른 글

if kakao 2021 - UI 테스트 경험기  (0) 2021.11.18
if kakao 2020 - Shared Elements Transition  (0) 2020.11.18
2020 NAVER TECH CONCERT 후기  (0) 2020.08.21

댓글