Android
 Computer >> コンピューター >  >> プログラミング >> Android

【Android】TextViewの一部だけをクリック可能にする方法|SpannableStringとClickableSpanの使い方

AndroidでTextViewの一部だけをクリック可能にする方法

Androidアプリ開発では、「利用規約」や「プライバシーポリシー」のように、長いテキストの中の特定の文字列だけをタップ可能にしたい場面があります。そんなときに役立つのがSpannableStringとClickableSpanです。

この記事では、TextView内の一部の文字列だけをクリック可能にする実装方法を、実際のサンプルコードとともにステップごとに解説します。

作成するアプリの概要

今回は「I want THIS and THIS to be CLICKED!」というテキストを表示し、そのうちの「THIS」「THIS」「CLICKED」の3箇所だけをタップできるようにします。各箇所をタップすると、対応するメッセージがToastで表示される仕組みです。

ステップ1:新規プロジェクトを作成する

Android Studioを開き、メニューから「File」→「New Project」を選択します。必要な情報を入力して新しいプロジェクトを作成しましょう。テンプレートは「Empty Activity」を選んでおけば問題ありません。

ステップ2:レイアウトファイルを作成する

res/layout/activity_main.xml に以下のコードを記述します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I want THIS and THIS to be CLICKED!"
        android:layout_centerInParent="true"
        android:textSize="16sp"
        android:textStyle="bold|italic"/>
</RelativeLayout>

RelativeLayoutの中にTextViewを1つ配置し、画面中央(layout_centerInParent)に表示するシンプルなレイアウトです。

ステップ3:MainActivity.javaを実装する

続いて、src/MainActivity.java に以下のコードを追加します。

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.textView);

        String text = "I want THIS and THIS to be CLICKED";
        SpannableString spannableString = new SpannableString(text);

        ClickableSpan clickableSpan1 = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "THIS", Toast.LENGTH_SHORT).show();
            }
        };

        ClickableSpan clickableSpan2 = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "THIS", Toast.LENGTH_SHORT).show();
            }
        };

        ClickableSpan clickableSpan3 = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Toast.makeText(MainActivity.this, "CLICKED", Toast.LENGTH_SHORT).show();
            }
        };

        spannableString.setSpan(clickableSpan1, 7, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(clickableSpan2, 16, 20, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        spannableString.setSpan(clickableSpan3, 27, 34, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        textView.setText(spannableString);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
    }
}

コードの解説:クリック可能にする仕組み

ここが本記事の核心部分です。処理の流れを整理すると以下の通りです。

  1. SpannableStringの生成:通常の文字列をSpannableStringに変換することで、部分的な装飾やイベント設定が可能になります。
  2. ClickableSpanの定義:onClick()メソッドをオーバーライドし、タップされたときの処理(ここではToast表示)を記述します。
  3. setSpan()で範囲を指定:第2引数に開始位置、第3引数に終了位置を渡します。たとえば setSpan(clickableSpan1, 7, 11, ...) なら、7文字目〜10文字目("THIS"の4文字)がクリック対象になります。
  4. MovementMethodの設定:textView.setMovementMethod(LinkMovementMethod.getInstance()) を呼び出すことで、ClickableSpanがタップイベントを受け取れるようになります。この設定を忘れるとクリックが一切反応しないので注意してください。

なお、文字位置のインデックスは0始まりで数えます。日本語テキストを扱う場合も、全角文字は1文字としてカウントされる点に留意しましょう。

ステップ4:AndroidManifest.xmlを確認する

androidManifest.xml は以下の通りです。今回の機能には特別なパーミッションは不要です。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android" package="app.com.sample">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

アプリを実行して動作を確認しよう

準備ができたらアプリを実行してみましょう。実機のAndroidスマートフォンをPCに接続している場合は、Android Studioでアクティビティファイルを開き、ツールバーの「Run」アイコンをクリックして、接続したデバイスを選択します。エミュレータでも同様に確認できます。

アプリが起動すると、まず次のような初期画面が表示されます。

【Android】TextViewの一部だけをクリック可能にする方法|SpannableStringとClickableSpanの使い方

「THIS」の部分をタップすると、対応するToastメッセージが表示されます。

【Android】TextViewの一部だけをクリック可能にする方法|SpannableStringとClickableSpanの使い方

「CLICKED」の部分をタップした場合も、それぞれ設定したメッセージが表示されることを確認できます。

【Android】TextViewの一部だけをクリック可能にする方法|SpannableStringとClickableSpanの使い方

補足:新しいプロジェクトでの注意点

近年のAndroid Studioで作成したプロジェクトでは、サポートライブラリ(android.support.v7.app.AppCompatActivity)ではなく、AndroidX(androidx.appcompat.app.AppCompatActivity)が標準となっています。import文をAndroidX向けに読み替えてください。また、Kotlinで実装する場合も考え方は同じで、spannable.setSpan(...) をそのまま利用できます。

まとめ

TextViewの一部をクリック可能にするには、SpannableString+ClickableSpan+LinkMovementMethodの3点セットを使います。setSpan()での文字位置指定ミスと、setMovementMethod()の設定漏れがつまずきやすいポイントなので、この2つを意識すればスムーズに実装できます。利用規約へのリンクや文中の用語解説など、さまざまなUIに応用できるテクニックなので、ぜひマスターしておきましょう。

  1. 【Android】エミュレータのIPアドレスを取得して表示する方法を解説

    はじめにこの記事では、Androidアプリから端末(エミュレータ/実機)のIPアドレスを取得し、画面に表示する方法を、実際のサンプルコードとともにステップ形式で解説します。Wi-Fi接続情報を利用したシンプルな実装例なので、Android開発初心者の方にもわかりやすい内容となっています。手順1:新規プロジェクトの作成まず、Android Studioで新しいプロジェクトを作成します。メニューから「File」→「New Project」を選択し、必要な項目を入力してプロジェクトを作成してください。手順2:レイアウトファイル(activity_main.xml)の編集res/layout/acti

  2. Androidで音楽スリープタイマーを設定する方法|寝落ちしても安心の自動停止テクニック

    スマホやタブレットで寝る前に音楽や動画を楽しむのは、一日の疲れを癒してくれる素敵な習慣ですよね。しかし、そのまま眠りに落ちてしまうと、メディアが朝まで再生され続けてしまうこともあります。そこで便利なのが「ミュージックスリープタイマー」です。 スリープタイマーとは、就寝前にセットできるカウントダウン機能のこと。設定した時間が経過すると、デバイス上のオーディオ再生が自動的に停止します。普段眠りに落ちる時間に合わせてカウントダウンを設定しておけば、自分が眠った瞬間にメディアも静かにしてくれるという仕組みです。 スリープタイマーを使うメリット スリープタイマーを活用する理由は人それぞれです。例えば、