관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] 안드로이드 Linkfy 적용 (하나의 텍스트에 링크를 여러개 달아주자) 본문

안드로이드/코틀린 & 아키텍처 & Recent

[안드로이드] 안드로이드 Linkfy 적용 (하나의 텍스트에 링크를 여러개 달아주자)

막무가내막내 2020. 7. 5. 16:46
728x90

 

[2021-04-14 업데이트]

 

 

 

예전에 텍스트 관련 라이브러리 중 Spanny라는 라이브러리를 사용한적이 있었는데요.

https://youngest-programming.tistory.com/79

 

[안드로이드] Spanny 라이브러리

Spanny 라이브러리에 대해 살펴보는 포스팅입니다. Spanny는 텍스트뷰와 같이 여러줄의 글이 올 수 있는 뷰의 스타일을 바꿔줄 수 있는 라이브러리입니다. 예를들어 안 녕 하 세 요.  또는 안 녕 하

youngest-programming.tistory.com

 

 

위와 같은 하나의 텍스트에 3개의 링크 (멀티링크) 그리고 다른 글자색과 굵기를 주어야했습니다.

단위별로 하나하나 텍스트 뷰로 나눌려다가 안좋은 방법 같아 바로 구글링을 시작!!

 

https://gun0912.tistory.com/66

 

[안드로이드/Android]Linkify로 TextView의 특정단어 클릭시 URL이동시키기

로그인이 필요한 대부분의 서비스를 보면 로그인화면에서 '...xxx의 이용약관, 개인정보 취급방침, ... 에 동의하시게 됩니다.' 라는 문구를 많이 보셨을겁니다. 여기서 '이용약관' 을 클릭하면 해

gun0912.tistory.com

박상권님의 블로그에 Linkfy 라는 것을 발견하게 되었습니다.

간단히 말하면 링크를 줄 텍스트의 패턴(정규식)을 정의하고 하나의 텍스트뷰에 적용하여 패턴에 맞는 다수의 글자에 링크를 걸어줄 수 있습니다.

자세한 설명은 위 블로그에 들어가면 자세하게 나옵니다 !!

다음과 같이 적용했습니다

//Transform 정의
        val transform =
            Linkify.TransformFilter(object : Linkify.TransformFilter, (Matcher, String) -> String {
                override fun transformUrl(p0: Matcher?, p1: String?): String {
                    return ""
                }

                override fun invoke(p1: Matcher, p2: String): String {
                    return ""
                }

            })
        //링크달 패턴 정의
        val pattern1 = Pattern.compile("취소 / 이용규정")
        val pattern2 = Pattern.compile("개인 정보 수집 / 이용 방침")
        val pattern3 = Pattern.compile("개인정보 제 3자 제공")
        Linkify.addLinks(text, pattern1, "http://www.naver.com", null, transform)
        Linkify.addLinks(text, pattern2, "http://www.google.com", null, transform)
        Linkify.addLinks(
            text,
            pattern3,
            "https://youngest-programming.tistory.com/",
            null,
            transform
        )

 

그럼 링크는 해결되었고 다음은 색상과 굵기를 조절해야 했습니다. 이것도 구글링 시작!!

링크가 걸린 색상만 변경하기위해 xml에 다음 속성을 적용했습니다.

android:textColorLink="#FF9800"
 <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/a"
        android:textSize="23sp"
        android:textColorLink="#FF9800"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

 

 

그리고 굵기를 위해서는 string.xml 에서 링크에 해당하는 글자에 <b> 태그를 주어 굵기를 주었고 코틀린에서는 Html.fromHtml 함수를 통해 html을 적용시켜 주었습니다.

<resources>
    <string name="app_name">My Application</string>
    <string name="a"><b>취소 / 이용규정</b>, <b>개인 정보 수집 / 이용 방침</b> 및 <b>개인정보 제 3자 제공</b>을 모두 읽었으며 이 에 동의합니다.</string>
</resources>
//HTML 적용
        text.text = HtmlCompat.fromHtml(getString(R.string.a), HtmlCompat.FROM_HTML_MODE_COMPACT)

 

 

 

결론적으로 전체 코드는 다음과 같습니다. (본 프로젝트에 적용 하기 전 테스트를 위해 샘플 프로젝트에 적용한걸 올린겁니다 참고바랍니다.)

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/a"
        android:textSize="23sp"
        android:textColorLink="#FF9800"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/text"
        >

        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="1000dp"
                android:scaleType="fitXY"
                android:src="@drawable/ic_launcher_background"
                app:layout_constraintTop_toTopOf="parent"
                />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<resources>
    <string name="app_name">My Application</string>
    <string name="a"><b>취소 / 이용규정</b>, <b>개인 정보 수집 / 이용 방침</b> 및 <b>개인정보 제 3자 제공</b>을 모두 읽었으며 이 에 동의합니다.</string>
</resources>
package com.mtjin.myapplication

import android.os.Bundle
import android.text.util.Linkify
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat
import kotlinx.android.synthetic.main.activity_main.*
import java.util.regex.Matcher
import java.util.regex.Pattern

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //HTML 적용
        text.text = HtmlCompat.fromHtml(getString(R.string.a), HtmlCompat.FROM_HTML_MODE_COMPACT)
        //Transform 정의
        val transform =
            Linkify.TransformFilter(object : Linkify.TransformFilter, (Matcher, String) -> String {
                override fun transformUrl(p0: Matcher?, p1: String?): String {
                    return ""
                }

                override fun invoke(p1: Matcher, p2: String): String {
                    return ""
                }

            })
        //링크달 패턴 정의
        val pattern1 = Pattern.compile("취소 / 이용규정")
        val pattern2 = Pattern.compile("개인 정보 수집 / 이용 방침")
        val pattern3 = Pattern.compile("개인정보 제 3자 제공")
        Linkify.addLinks(text, pattern1, "http://www.naver.com", null, transform)
        Linkify.addLinks(text, pattern2, "http://www.google.com", null, transform)
        Linkify.addLinks(
            text,
            pattern3,
            "https://youngest-programming.tistory.com/",
            null,
            transform
        )

    }
}

 

 

 

[결과화면]

링크도 잘 타짐을 볼 수 있었습니다.

 

 

댓글과 공감은 큰 힘이 됩니다. 감사합니다!!

728x90
Comments