3 голоса
 
595 просмотров
30.01.2019 / 08:40  Nolosha

Подсветка синтаксиса

На андроид мне нужно подсветить некоторые слова в Edittext. Вот к примеру, мне надо подсвечивать слова "public". Ну и нашла такой пример:
  1. editText.addTextChangedListener(new TextWatcher() {
  2.     final String FUNCTION = "public";
  3.     @Override
  4.     public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
  5.  
  6.     @Override
  7.     public void onTextChanged(CharSequence s, int start, int before, int count) {}
  8.  
  9.     @Override
  10.     public void afterTextChanged(Editable s) {
  11.         int index = s.toString().indexOf(FUNCTION);
  12.         if (index >= 0) {
  13.             s.setSpan(
  14.                     new ForegroundColorSpan(Color.CYAN),
  15.                     index,
  16.                     index + FUNCTION.length(),
  17.                     Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  18.         }
  19.     }
  20. });
Скажу результат: посветка действует только на одно слово public т.е. самое первое. И если я стеру одну из букв слова public (которое подсвечено), то слово publi горит цветом все равно! Хоть до первой буквы стери!
Как же можно сделать нормальную подсветку?
Изм. Nolosha от 30.01.2019 / 08:46
Ответы
 
1 голос
 
# 30.01.2019 / 16:02  aNNiMON
Сначала получаем список ключевых слов, которые нужно подсветить. Нужны именно позиции начала и конца. И span очищать нужно обязательно.
  1. // new TextWatcher() { ...
  2. @Override
  3. public void afterTextChanged(Editable s) {
  4.     highlight(s);
  5. }
  6. // ...
  7.  
  8. private void highlight(Editable editable) {
  9.     final List<SyntaxHighlightToken> tokens = Lexer.highlight(editable.toString());
  10.     clearSpans(editable);
  11.     for (SyntaxHighlightToken token : tokens) {
  12.         final int from = token.getFrom();
  13.         final int to = token.getTo();
  14.         editable.setSpan(new ForegroundColorSpan(keywordColor),
  15.                 from, to, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
  16.     }
  17. }
  18.  
  19. private void clearSpans(Editable editable) {
  20.     ForegroundColorSpan[] foregroundSpans = editable.getSpans(0, editable.length(), ForegroundColorSpan.class);
  21.     for (int i = foregroundSpans.length; i-- > 0; ) {
  22.         editable.removeSpan(foregroundSpans[i]);
  23.     }
  24. }
30.01.2019 / 17:41  Nolosha
Спасибо большое!
 
1 голос
 
# 30.01.2019 / 12:36  Askalite
Не проверял
Открыть спойлер

Перед изменением подсветки старую надо удалять
30.01.2019 / 17:42  Nolosha
Спасибо большое!
 
0 голосов
 
# 30.01.2019 / 18:06  Nolosha
aNNiMON, а что за классы Lexer, SyntaxHighligterToken? Среда не знает таких
Изм. Nolosha от 30.01.2019 / 18:06
30.01.2019 / 19:59  aNNiMON
Это уже сами реализовывайте. Вместо них s.indexOf(FUNCTION) будет или может полноценный лексер сделаете, чтобы подсвечивало только там, где нужно.
Всего: 3

Реклама

Мы в соцсетях

tw tg yt gt