web-dev-qa-db-ja.com

Android-TextViewで単語を強調表示しますか?

ユーザーが入力した単語をデータベースで検索してCursorを返す_database search query_があります。

私のListActivityには、アイテム(カーソルアイテム)を保持するListViewがあります。 ListViewアイテムのレイアウトは基本的にTextViewです。つまり、ListViewTextViewのリストになります。

_search term_がTextViewのどこにあるかを強調表示したいのですが。ハイライトとは、色が違う、背景色が違う、などの理由でテキストの他の部分と違うということです。

これは可能ですか?どうやって?

更新:

_cursor = myDbHelper.search(term);  //term: a Word entered by the user.
cursor.moveToFirst();
String[] columns = {cursor.getColumnName(1)}; 
int[] columnsLayouts = {R.id.item_title}; //item_title: the TextView holding the one raw
ca = new SimpleCursorAdapter(this.getBaseContext(), R.layout.items_layout, cursor,columns , columnsLayouts);
lv = getListView();
lv.setAdapter(ca);
_

@Shailendraの場合:search()メソッドはいくつかのタイトルを返します。タイトルのterm単語に一致する単語を強調表示したい。これが明確になったことを願っています。

30
iTurki

wordの周りに色のHTMLコードを挿入し、それをtextViewに設定します。

お気に入り

String newString = oldString.replaceAll(textToHighlight, "<font color='red'>"+textToHighlight+"</font>");
textView.setText(Html.fromHtml(newString));
TextView textView = (TextView)findViewById(R.id.mytextview01);

//use a loop to change text color
Spannable WordtoSpan = new SpannableString("partial colored text");        
WordtoSpan.setSpan(new ForegroundColorSpan(Color.BLUE), 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(WordtoSpan);

番号2と4は、テキストの色付けの開始/停止インデックスです。この例では、「rti」が色付けされます。

したがって、基本的には、タイトルに検索ワードの開始インデックスを見つけるだけです。

int startIndex = titleText.indexOf(term);
int stopIndex = startIndex + term.length();

次に、数字の2と4をインデックスで置き換え、「部分的な色のテキスト」をタイトル文字列で置き換えます。

ソース: https://stackoverflow.com/a/10279703/2160827

21
finstas

私はそれが古い質問であることを知っていますが、string\paragraphで繰り返し単語を強調表示するメソッドを作成しました。

private Spannable highlight(int color, Spannable original, String Word) {
    String normalized = Normalizer.normalize(original, Normalizer.Form.NFD)
            .replaceAll("\\p{InCombiningDiacriticalMarks}+", "");

    int start = normalized.indexOf(Word);
    if (start < 0) {
        return original;
    } else {
        Spannable highlighted = new SpannableString(original);
        while (start >= 0) {
            int spanStart = Math.min(start, original.length());
            int spanEnd = Math.min(start+Word.length(), original.length());

            highlighted.setSpan(new ForegroundColorSpan(color), spanStart,
                    spanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);

            start = normalizedText.indexOf(Word, spanEnd);
        }
        return highlighted;
    }
}

使用法:

textView.setText(highlight(primaryColor, textAll, wordToHighlight));
4
Sumit

私はそれをしていませんが、これは有望に見えます:

http://developer.Android.com/reference/Android/text/SpannableString.html
http://developer.Android.com/guide/topics/resources/string-resource.html

public final void setText(CharSequence text)

導入:APIレベル1 TextViewの文字列値を設定します。 TextViewはHTMLのようなフォーマットを受け入れません。これは、XMLリソースファイルのテキスト文字列で行うことができます。文字列のスタイルを設定するには、Android.text.style。*オブジェクトをSpannableStringにアタッチするか、XMLリソースファイルでフォーマットされたテキストを設定する例について、利用可能なリソースタイプのドキュメントをご覧ください。

http://developer.Android.com/reference/Android/widget/TextView.html

2
Tim

より簡単な方法

Spannable クラスを使用して、テキストの一部を強調表示/フォーマットできます。

textView.setText("Hello, I am Awesome, Most Awesome"); // set text first
setHighLightedText(textView, "a"); // highlight all `a` in TextView

Output

こちらがその方法です。

 /**
     * use this method to highlight a text in TextView
     *
     * @param tv              TextView or Edittext or Button (or derived from TextView)
     * @param textToHighlight Text to highlight
     */
    public void setHighLightedText(TextView tv, String textToHighlight) {
        String tvt = tv.getText().toString();
        int ofe = tvt.indexOf(textToHighlight, 0);
        Spannable wordToSpan = new SpannableString(tv.getText());
        for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
            ofe = tvt.indexOf(textToHighlight, ofs);
            if (ofe == -1)
                break;
            else {
                // set color here
                wordToSpan.setSpan(new BackgroundColorSpan(0xFFFFFF00), ofe, ofe + textToHighlight.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
            }
        }
    }

この答えを確認してください をクリックして強調表示されたテキストを表示できます。

1
Khemraj

このライブラリを試してください Android TextHighlighter

実装

TextView.setText()は、Spannableだけでなく、CharacterSequenceとしてパラメーターを取得します。 SpannableStringには、スタイルを適用できるsetSpan()メソッドがあります。

直接のサブクラスフォームCharacterStyleのリストを参照してください https://developer.Android.com/reference/Android/text/style/CharacterStyle.html

  • 「Hello、World」の「Hello」という言葉に背景色と前景色を与える例
Spannable spannable = new SpannableString("Hello, World");
// setting red foreground color
ForegroundSpan fgSpan = new ForegroundColorSpan(Color.red);
// setting blue background color
BackgroundSpan bgSpan = new BackgroundColorSPan(Color.blue);

// setSpan requires start and end index
// in our case, it's 0 and 5
// You can directly set fgSpan or bgSpan, however,
// to reuse defined CharacterStyle, use CharacterStyle.wrap()
spannable.setSpan(CharacterStyle.wrap(fgSpan), 0, 5, 0);
spannable.setSpan(CharacterStyle.wrap(bgSpan), 0, 5, 0);

// apply spannableString on textview
textView.setText(spannable);
1
xeoh

xml strings文字列が静的な場合

<string name="my_text">This text is <font color='red'>red here</font></string>
1
Isaac Sekamatte

私はこのスレッドが古いことを知っていますが、誰かがテキストビューで文字列を強調表示しようとしている場合に備えて、これを正確に実行するライブラリを作成しました。スタックオーバーフローに関する質問に対するこれが私の最初の回答です。参加したばかりなので、適切にフォーマットされ、適切であることを願っています。 SpannableStringを使用し、指定した文字列のすべての出現箇所を検索します。さらに、カスタムClickableSpanが組み込まれており、必要に応じてクリックされたテキストのリスナーを設定できます。

リンカ

軽量Android textview内の文字列を強調するためのライブラリ(大文字と小文字の区別なし)、オプションのコールバック付き)。

言語:Java

MinSDK:17

その機能とすべてのコードの画像は here にあります。

JavaDocs

Androidプロジェクトに組み込むには、アーティファクトを実装します。

プロジェクトレベルのbuild.gradle

    allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

アプリレベルのbuild.gradle

       dependencies {
            implementation 'com.github.Gaineyj0349:Linker:1.2'
    }

使い方:

1-テキストビューでリンカーオブジェクトを作成します。

        Linker linker = new Linker(textView);

2-テキストビューのテキスト内で強調表示される配列または文字列のリストを追加します。

        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        linker.addStrings(list);

AND/OR

        String[] words = new String[]{"One", "Two", "Three"};
        linker.addStrings(words);

3-コールバックを追加します:(これはオプションです):

       linker.setListener(new LinkerListener() {
            @Override
            public void onLinkClick(String charSequenceClicked) {

                // charSequenceClicked is the Word that was clicked

                Toast.makeText(MainActivity.this, charSequenceClicked, Toast.LENGTH_SHORT).show();
            }
        });

4-リンカーのupdateメソッドを呼び出して、カスタマイズをコミットし、セットアップをロールアウトします。

        linker.update();

常にリンカオブジェクトに文字列を追加するオプションがあります。スパンを更新するには、必ず更新メソッドを呼び出してください。

    linker.addStrings("yoda");
    linker.update();

同じリンカーオブジェクトを使用して新しいスレートが必要な場合は、

       linker.clearLinksList()

リンクをカスタマイズすることもできます。

1-すべてのリンクの色をカスタマイズします。

      linker.setAllLinkColors(Color.BLUE);

2-リンクの下線をカスタマイズします。

      linker.setAllLinkUnderline(false);

3-特定の文字列の色または下線の設定をカスタマイズする場合(文字列は既にリンカーに追加されている必要があります):

      linker.setLinkColorForCharSequence("world", Color.Magenta);
      linker.setUnderlineModeForCharSequence("world", true);

4-Wordごとに異なる設定を使用する場合は、リンカーオブジェクトにLinkProfileのリストまたは配列を指定することもできます。

        ArrayList<LinkProfile> profiles = new ArrayList<>();
        profiles.add(new LinkProfile("hello world",
                Color.GREEN, false));
        profiles.add(new LinkProfile("goodbye cruel world",
                Color.RED, false));
        profiles.add(new LinkProfile("Whoa awesome!",
                Color.CYAN, true));


        linker.addProfiles(profiles);

リンカーオブジェクトに追加した後は、必ず.update()を呼び出すようにしてください。

ライブラリは、同じ単語を2つ追加したり、単語の同じ部分を追加したりするなど、細かい処理を行います。たとえば、「helloworld」と「hello」がリンカに追加された2つの単語である場合、「helloworld」は、同じ文字の範囲内にある場合、「hello」よりも優先されます。リンカは、最初に大きな単語に従ってソートし、リンクするときにすべてのスパンをトレースします。これにより、重複や交差するスパンの問題が回避されます。

MITライセンスの下でライセンスされています。

0
Joshua Gainey