Подтвердить что ты не робот

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

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

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

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

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

и ниже - код для сохранения моих заметок на SD-карте.

            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>&#160; a&#160; <font color ="#04ff00"><b><font style = "background-color:#2929dd">String</font></b></font>... </p>

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

Edit

Ниже приведен код, который я использовал для извлечения текста из файла 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);
4b9b3361

Ответ 1

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

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

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

Итак, я разделяю содержимое этого класса, чтобы вы могли получить от него идею установить Backround Color в 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) Вот мой Шрифт класс

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

            }
        }

    }
}

Ответ 2

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

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

Ответ 3

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

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

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

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

  • начало, конец, цвет для каждого диапазона

  • ваш текст

В следующем фрагменте кода показано, как реализовать методы хранения и загрузки. Он использует текст Spanned в 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);
    }
}

Ответ 4

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

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

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

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

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

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

Ответ 5

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

Скорее старый пост в блоге Commonware содержит список рабочих атрибутов.

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

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

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

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