이 게시물에서는 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의 확장
👉속성 이름에 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 2021 - UI 테스트 경험기 (0) | 2021.11.18 |
---|---|
if kakao 2020 - Shared Elements Transition (0) | 2020.11.18 |
2020 NAVER TECH CONCERT 후기 (0) | 2020.08.21 |
댓글