Как получить BackgroundColorSpan для выбранного текста в android

Я пытаюсь установить BackgroundColorSpan на выделенный текст в моем Редактировании-тексте . Поэтому, когда я выбираю любой текст и нажимаю кнопку, он устанавливает цвет фона для этого конкретного текста, а затем я сохраняю эту заметку на SDCard с форматом .html , а затем снова получаю эту заметку для редактирования снова в том же формате.

Проблема, с которой я столкнулся сейчас, – это когда я применяю BackgroundColorSpan к выбранному тексту, который показывает эту строку с цветом фона, который я применил, но как только я сохраню эту заметку на SDCard и снова открою, она не отображает цвет фона для этой конкретной строки Из этого он показывает мне нормальную строку без цвета фона.

Ниже мой код Который я использовал, чтобы установить цвет фона в выделенную область редактирования текста

mSpannable.setSpan(new BackgroundColorSpan(color),startSelection, endSelection, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 

И ниже – код для сохранения моих заметок на SDcard.

  Spanned spannedText = edtNoteDescription.getText(); StringBuilder output = new StringBuilder(); AppHtml.withinHtml(output, spannedText); File mFile = new File(Environment.getExternalStorageDirectory() + File.separator + "MyNote/"); } File myFile = new File(mFile, "/" + strNoteTitle + ".html/"); myFile.createNewFile(); FileOutputStream fOut = new FileOutputStream(myFile); OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut); myOutWriter.append(output); myOutWriter.close(); fOut.close(); 

С помощью этого выше кода я успешно могу сохранить файл в формате HTML, но я не получаю строку с цветом фона.

Я попытался напечатать эту строку в журнале, а затем вставить эту строку в w3School, после чего получаю точный результат, которого я ожидаю, но в андроиде я не знаю, почему он не работает.

Строка, которую я получаю в Logcat, ниже

 <p><font color ="#7dff00">This</font> <font color ="#ff5100">Is</font>  a  <font color ="#04ff00"><b><font style = "background-color:#2929dd">String</font></b></font>... </p> 

Вы можете попробовать эту строку здесь, которая дает прекрасный результат с цветом фона в строку, но при настройке на android Edit-ext я не знаю, что происходит, и это не настройка, как я ожидаю.

редактировать

Ниже приведен код, который я использовал для извлечения текста из файла SDcard

  Bundle bundle = getIntent().getExtras(); strGetPath = bundle.getString(GlobalClass.notesPath); filePath = new File(strGetPath); fileInputStream = new FileInputStream(filePath); int size = fileInputStream.available(); bytbuffer = new byte[size]; fileInputStream.read(bytbuffer); fileInputStream.close(); String strGetData = new String(bytbuffer); Spanned spanHTMLData = AppHtml.fromHtml(strGetData); LogM.e("===== Getting Data =====" + strGetData); edtNoteDescription.setText(spanHTMLData); 

Та же проблема, с которой я столкнулся при создании проекта сохранения заметок HTML.

Как вы сказали, что вы создали свой собственный класс HTML.java, я также настроил тот же класс для своей цели.

По умолчанию класс Html.java не содержит функций для фона, размера шрифта, пули и т. Д.

Итак, я разделяю содержимое этого класса, чтобы вы могли получить от него идею установить цвет фона Backside в HTML-примечание.

Предположим, что вы настроили Html.java = AppHtml.java, чтобы другие могли лучше понять это.

1) Сначала добавьте тег цвета фона в свой класс AppHtml.java . Добавьте этот ниже код в свой метод внутри .

 if (style[j] instanceof BackgroundColorSpan) { out.append("<font style = \"background-color:#"); String color = Integer .toHexString(((BackgroundColorSpan) style[j]) .getBackgroundColor() + 0x01000000); while (color.length() < 6) { color = "0" + color; } out.append(color); out.append("\">"); } 

Затем заполните стиль шрифта, который вы начали

 if (style[j] instanceof BackgroundColorSpan) { out.append("</font>"); } 

2) Вот мой класс Font

 private static class Font { public String mColor; public String mFace; public String mbgColor; public String mSize; public Font(String color, String face, String bgColor, String size) { mColor = color; mFace = face; mbgColor = bgColor; mSize = size; } } 

3) Вот мой метод startFont .

 private static void startFont(SpannableStringBuilder text, Attributes attributes) { String color = attributes.getValue("", "color"); String face = attributes.getValue("", "face"); String bgColor = attributes.getValue("", "style"); String size = attributes.getValue("", "size"); int len = text.length(); text.setSpan(new Font(color, face, bgColor, size), len, len, Spannable.SPAN_MARK_MARK); } 

4) Вот мой метод endFont .

 private static void endFont(SpannableStringBuilder text) { int len = text.length(); Object obj = getLast(text, Font.class); int where = text.getSpanStart(obj); text.removeSpan(obj); if (where != len) { Font f = (Font) obj; if (f.mColor != null) { if (!TextUtils.isEmpty(f.mColor)) { if (f.mColor.startsWith("@")) { Resources res = Resources.getSystem(); String name = f.mColor.substring(1); int colorRes = res.getIdentifier(name, "color", "android"); if (colorRes != 0) { ColorStateList colors = res .getColorStateList(colorRes); text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { int c = getHtmlColor(f.mColor); if (c != -1) { text.setSpan( new ForegroundColorSpan(c | 0xFF000000), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } } if (f.mFace != null) { text.setSpan(new TypefaceSpan(f.mFace), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (f.mbgColor != null) { String bg_COLOR = f.mbgColor.substring( f.mbgColor.lastIndexOf("#"), f.mbgColor.length()); if (!TextUtils.isEmpty(bg_COLOR)) { if (bg_COLOR.startsWith("@")) { Resources res = Resources.getSystem(); String name = bg_COLOR.substring(1); int colorRes = res.getIdentifier(name, "color", "android"); if (colorRes != 0) { ColorStateList colors = res .getColorStateList(colorRes); text.setSpan(new TextAppearanceSpan(null, 0, 0, colors, null), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { int c = getHtmlColor(bg_COLOR); if (c != -1) { text.setSpan( new BackgroundColorSpan(c | 0xFF000000), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } } if (f.mSize != null) { if (!TextUtils.isEmpty(f.mSize)) { int size = Integer.parseInt(f.mSize); text.setSpan((new AbsoluteSizeSpan(size)), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } } 

Я не знаю, что такое AppHtml в исходном коде, но для Html <-> Spannable parsing в Android мы используем класс android.text.Html . По какой-то причине этот класс не поддерживает BackgroundColorSpan .

Я бы предложил экспериментировать с Html.fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler) и передать TagHandler для поддержки того, что вам нужно. Документы здесь .

  • Создайте свой собственный формат и сохраните его в файле

Я не знаю, это именно то, что вы ищете, но я не вижу смысла использовать HTML здесь. Как указывалось в других ответах, fromHtml() довольно ограничен, и использование пользовательского формата файла решит вашу проблему сохранения / восстановления в кратчайшие сроки.

Вам необходимо сохранить в файле следующие данные:

  1. Сколько пролетов у вас есть

  2. Начало, конец, цвет для каждого пролета

  3. ваш текст

В следующем фрагменте кода показано, как реализовать методы хранения и загрузки. Он использует Spanned text в TextView . Полный проект Eclipse занял у меня около получаса, и его можно найти здесь .

 public void store(View v) { Spanned s = (Spanned) mTextView.getText(); BackgroundColorSpan[] spans = s.getSpans(0, s.length(), BackgroundColorSpan.class); BufferedWriter bw = null; try { int len = spans.length; bw = new BufferedWriter(new FileWriter(mFile)); bw.write(String.valueOf(len)); bw.newLine(); for (BackgroundColorSpan span : spans) { int start = s.getSpanStart(span); int end = s.getSpanEnd(span); int color = span.getBackgroundColor(); bw.write("" + start + "," + end + "," + color); bw.newLine(); } bw.write(mText); clear(v); } catch (IOException e) { Log.e(TAG, "IO error", e); } finally { closeQuietly(bw); } } public void load(View v) { BufferedReader br = null; try { br = new BufferedReader(new FileReader(mFile)); int len = Integer.parseInt(br.readLine()); BackgroundColorSpan[] spans = new BackgroundColorSpan[len]; int[] starts = new int[len]; int[] ends = new int[len]; for (int i = 0; i < len; i++) { String[] tokens = br.readLine().split(","); starts[i] = Integer.parseInt(tokens[0]); ends[i] = Integer.parseInt(tokens[1]); int color = Integer.parseInt(tokens[2]); spans[i] = new BackgroundColorSpan(color); } mText = br.readLine(); SpannableString s = new SpannableString(mText); for (int i = 0; i < len; i++) { s.setSpan(spans[i], starts[i], ends[i], Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } mTextView.setText(s); } catch (IOException e) { Log.e(TAG, "IO error", e); } finally { closeQuietly(br); } } 

Текущая реализация Html.fromHtml поддерживает только color и typeface атрибуты Font . Вы можете проверить то же самое здесь .

Как вы сказали, вы используете модифицированную версию Html , гораздо проще поддерживать дополнительные атрибуты самостоятельно.

При разборе XML, когда обнаруживается тег open open, все значения атрибута шрифта хранятся в закрытом классе Font . Когда встречается тег закрытия шрифта, для каждого из этих атрибутов применяйте соответствующие стили span.

Шаг 1: В закрытом классе Font добавьте элемент данных для хранения фона и измените конструктор, чтобы принять дополнительный параметр.

 private static class Font { ... public String mBackgroundColor; // Data member to hold background color public Font(String color, String face, String backgroundColor) { ... mBackgroundColor = backgroundColor; } ... } 

Шаг 2. В методе startFont обработайте атрибут background-color .

 private static void startFont(SpannableStringBuilder text, Attributes attributes) { ... String backgroundColor = null; // In this specific example, background-color attribute is present in style attribute. String style = attributes.getValue("", "style"); if(style != null && style.contains("background-color")) { String[] array = style.split(":"); if(array.length == 2) backgroundColor = array[1]; } else { // If background-color is specified as an attribute itself use this backgroundColor = attributes.getValue("", "background-color"); } // Pass the background-color to the Font constructor text.setSpan(new Font(color, face, backgroundColor), len, len, Spannable.SPAN_MARK_MARK); } 

Шаг 3: В методе endFont добавьте BackgroundColorSpan к тексту.

 private static void endFont(SpannableStringBuilder text) { ... if(f.mBackgroundColor != null) { text.setSpan(new BackgroundColorSpan(Color.parseColor(f.mBackgroundColor)), where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } 

PS: Поскольку конструктор Html является закрытым, специализация Html невозможна.

К сожалению fromHtml() довольно ограничен, и он не может разобрать атрибут стиля шрифта .

В довольно старой записи в блоге Commonware есть список рабочих атрибутов.

У вас есть несколько вариантов:

  • Установите промежутки фона вручную
  • Создайте свой собственный синтаксический анализатор, который поддерживает это и делится им с публикой (yay)
  • Использовать WebView

Теперь использование WebView похоже на самое решение straighforward, вот пример:

 WebView webView = (WebView) findViewById(R.id.webView); String strGetData = "<p><font color =\"#7dff00\">This</font> <font color =\"#ff5100\">Is</font>&#160; a&#160; <font color =\"#04ff00\"><b><font style = \"background-color:#2929dd\">String</font></b></font>... </p>\n"; webView.loadData(strGetData, "text/html", "utf-8");