Android - выделить слово в TextView? - PullRequest
26 голосов
/ 27 июля 2011

У меня есть database search query, который ищет в базе данных слово, введенное пользователем, и возвращает Cursor.

В моем ListActivity у меня есть ListView, который будет содержатьпредметы (предметы Cursor).Расположение элементов ListView в основном равно TextView.Я имею в виду, что ListView будет списком TextView.

Я хочу выделить 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.Надеюсь, теперь все ясно.

Ответы [ 8 ]

38 голосов
/ 27 июля 2011

вставьте HTML-код цвета вокруг слова и установите его для вашего textView.

как

String newString = oldString.replaceAll(textToHighlight, "<font color='red'>"+textToHighlight+"</font>");
textView.setText(Html.fromHtml(newString));
21 голосов
/ 24 апреля 2013
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

4 голосов
/ 06 ноября 2017

Я знаю, что это старый вопрос, но я создал метод для выделения повторяющегося слова в строке \ абзаце.

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));
2 голосов
/ 27 июля 2011

Я не сделал этого, но это выглядит многообещающе:

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)

Since: API Level 1 Устанавливает значение строкиTextView.TextView не поддерживает HTML-подобное форматирование, что можно делать с текстовыми строками в файлах ресурсов XML.Чтобы стилизовать ваши строки, присоедините объекты android.text.style. * К SpannableString или посмотрите документацию «Доступные типы ресурсов» для примера настройки форматированного текста в файле ресурсов XML.

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

1 голос
/ 01 декабря 2018

Более легкий путь

Вы можете использовать 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 голос
/ 23 июля 2018

Вы делаете это в xml strings, если ваши строки статичны

<string name="my_text">This text is <font color='red'>red here</font></string>
1 голос
/ 25 августа 2017

Попробуйте эту библиотеку Android TextHighlighter .

Реализация

TextView.setText() получает параметр как Spannable не только CharacterSequence. SpannableString имеет метод setSpan(), который позволяет применять стили.

См. Список форм прямого подкласса CharacterStyle https://developer.android.com/reference/android/text/style/CharacterStyle.html

  • пример задания цвета фона и цвета переднего плана для слова «Hello» в «Hello, World»
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);
0 голосов
/ 21 апреля 2019

Я знаю, что эта ветка старая, но на всякий случай, если кто-то хочет выделить строки в текстовом представлении, я создал библиотеку, которая делает именно это. Это мой первый ответ на вопрос о переполнении стека, поскольку я только что присоединился, надеюсь, он отформатирован правильно и актуально. Он использует SpannableString и найдет все вхождения указанной вами строки. Кроме того, встроенный пользовательский ClickableSpan дает вам возможность при желании настроить прослушиватели для текста, по которому щелкают.

Linker

Облегченная библиотека Android для выделения строк внутри текстового представления (без учета регистра) с необязательными обратными вызовами.

Язык: Java

MinSDK: 17

Изображение его функциональности и всего кода можно найти здесь .

JavaDocs

Чтобы внести в свой проект Android реализацию артефакта:

На уровне проекта build.gradle

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

На уровне приложения build.gradle

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

Как использовать:

1 - создание объекта Linker с текстовым обзором:

        Linker linker = new Linker(textView);

2 - Добавить массив или список строк для выделения в тексте textview:

        ArrayList<String> list = new ArrayList<>();
        list.add("hello");
        list.add("world");
        linker.addStrings(list);
* * +1034 И / ИЛИ * * тысячу тридцать-пять
        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 - вызов метода обновления компоновщика, чтобы зафиксировать настройку и развернуть настройку .:

        linker.update();

У вас всегда есть возможность добавить строки в объект компоновщика, просто убедитесь, что вы вызываете метод 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 - Если вы хотите использовать различные настройки для каждого слова, вы также можете предоставить объекту компоновщика список или массив LinkProfiles:

        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 () после любых добавлений к объекту компоновщика.

Обратите внимание, что библиотека позаботится о таких тонкостях, как добавление двух одинаковых слов или одинаковых частей слова. Например, если «helloworld» и «hello» - это два слова, добавленные в компоновщик, «helloworld» будет отдаваться предпочтение перед «hello», когда они находятся в одном и том же диапазоне символов. Компоновщик будет сначала сортировать по более крупным словам и отслеживать все промежутки по мере их связывания, избегая как дублирования, так и пересекающихся интервалов.

Лицензировано по лицензии MIT.

...