8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

リンクを含んだTextViewの実装〜タップアニメーションも

Last updated at Posted at 2018-08-11

はじめに

アプリを実装していて、「お問い合わせはこちら」のようなTextViewにリンクを含んだTextViewが作れないかと思ったことはありませんか?

screenhere.png

方法

今回は「お問い合わせはこちら」の「こちら」だけをリンク化したいと思います。
まず、ClickableSpan()というものを使用します。
指定した範囲の色やアンダーライン、そしてタップした時のイベントを登録することができます。

class MyClickableSpan(private val context: Context, private val textView: TextView) : ClickableSpan() {

    override fun updateDrawState(ds: TextPaint) {
        super.updateDrawState(ds)

        // リンク化する箇所の色を指定
        ds.linkColor = ContextCompat.getColor(context, R.color.colorAccent)

        // リンク化する箇所のアンダーラインの有無を指定
        ds.isUnderlineText = false
    }

    override fun onClick(p0: View?) {
        // お好きな処理をどうぞ
    }
}

そして、リンク化する範囲をどうやって決めるのかと言うと、
PatternとSpannableStringを使用します。

fun setTextLink(context: Context, textView: TextView) {
    // テキストはstrings.xmlから参照
    // 「こちら」のパターンを指定
    val pattern = Pattern.compile(getString(R.string.here))
        
    // TextViewにセットした「お問い合わせはこちら」から「こちら」を探す
    val matcher = pattern.matcher(textView.text)

    // SpannableStringを指定。これを使ってClickableSpanの適用範囲を決定
    val spannableString = SpannableString(getString(R.string.text))
    
    var start = 0
    var end = 0

    //「こちら」という文字がどこから始まり、どこで終わるのかを探し変数に収める
    while (matcher.find()) {
        start = matcher.start()
        end = matcher.end()
    }

    // SpannableStringのうち、MyClickableSpanを適用する範囲を指定
    spannableString.setSpan(MyClickableSpan(context, textView), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE)

    // TextViewにSpannableStringを適用
    textView.text = spannableString

    // リンク機能を適用
    textView.movementMethod = LinkMovementMethod.getInstance()
}

これでひとまず、TextViewにリンクを追加することができました。

おまけ - タップアニメーションを追加

このままでも十分なのですが、せっかくなのでリンクを押した時のハイライトを追加してみましょう。
先ほどのMyClickableSpanのupdateDrawState()に、textView.isPressedを使った条件文を追加します。

class MyClickableSpan(private val context: Context, private val textView: TextView) : ClickableSpan() {

    override fun updateDrawState(ds: TextPaint) {
        super.updateDrawState(ds)

        // リンク化する箇所の色を指定
        ds.linkColor = ContextCompat.getColor(context, R.color.colorAccent)

        // リンク化する箇所のアンダーラインの有無を指定
        ds.isUnderlineText = false

        // 新規追加
        // TextViewが押された時はハイライト色を変える
        if (textView.isPressed) {
            textView.highlightColor = ContextCompat.getColor(context, R.color.colorPrimaryDark)
        } else {
            textView.highlightColor = ContextCompat.getColor(context, R.color.white)
        }

        // TextViewの描画を更新
        textView.invalidate()
    }

    override fun onClick(p0: View?) {
        // お好きな処理をどうぞ
    }
}

これを適用すると、下のように「こちら」をタップした時にハイライト色が変化します。
(もちろん指を離すとisPressed=falseで指定した色に戻ります!)

screenlink2.png

ということで、今回はAndroidのリンクを含んだTextViewの実装方法を紹介しました。

8
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?