Android - выделить Word в текстовом виде?

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

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

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

Ответ 1

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

лайк

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

Ответ 2

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 индексами и "частичным цветным текстом" на свою строку заголовка.

источник: fooobar.com/questions/774334/...

Ответ 3

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

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

public final void setText (текст CharSequence)

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

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

Ответ 4

Я знаю этот старый вопрос, но я создал метод выделения повторного слова в строке \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));

Ответ 5

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

Реализации

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

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

  • пример предоставления цвета фона и цвета переднего плана для слова "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 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);

Ответ 6

Вы делаете это в xml strings если ваши строки являются статическими

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

Ответ 7

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

Вы можете использовать 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);
            }
        }
    }

Вы можете проверить этот ответ на кликабельный выделенный текст.

Ответ 8

Я знаю, что эта ветка старая, но на всякий случай, если кто-то хочет выделить строки в текстовом представлении, я создал библиотеку, которая делает именно это. Это мой первый ответ на вопрос о переполнении стека, так как я только что присоединился, надеюсь, он отформатирован правильно и актуально. Он использует 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.1'
    }

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

1 - Построить объект Linker с помощью textview:

        Linker linker = new Linker(textView);

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

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

И/ИЛИ

        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();

У вас всегда есть возможность добавить Strings в объект компоновщика, просто убедитесь, что вы вызываете метод 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.