如何在android中检索所选文本的BackgroundColorSpan



我正在尝试将BackgroundColorSpan设置为编辑文本中的选定文本。因此,当我选择任何文本并单击按钮时,它将为该特定文本设置背景色,然后我将该笔记以.html格式保存到我的SDCard中,然后我再次检索该笔记以相同格式再次编辑。

我现在面临的问题是,当我将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中,然后我得到了我期望的确切结果,但在android中,我不知道为什么它不起作用。

我在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编辑文本时,我不知道发生了什么,它没有像我期望的那样设置。

编辑

下面是我用来从SD卡文件中检索文本的代码

            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类不包含背景颜色、字体大小、项目符号等的功能。

因此,我在这里分享该类的内容,这样您就可以从中获得为HTML Note设置背景颜色的想法。

让我们假设您的自定义Html.java=AppHtml.java,这样其他人就能更好地理解它。

1)首先在AppHtml.java类中添加背景色标记。将下面的代码添加到您的withinPage方法中。

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<->在Android中,我们使用android.text.Html类进行可扩展解析。由于某些原因,这个类不支持BackgroundColorSpan

我建议尝试Html.fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)方法,并通过TagHandler来支持您需要的内容。文件在这里。

  • 创建自己的自定义格式并将其保存到文件中

我不知道这是否正是你想要的,但我不认为在这里使用HTML有什么意义。正如其他答案所指出的,fromHtml()非常有限,使用您的自定义文件格式将很快解决您的保存/恢复问题。

您需要在文件中存储以下信息:

  1. 的跨度有多少

  2. 每个跨度的开始、结束和颜色

  3. 您的文本

下面的代码片段显示了如何实现存储和加载方法。它使用TextView中的Spanned文本。完整的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的当前实现仅支持Fontcolortypeface属性。你可以在这里查看同样的内容。

正如您所说的,您使用的是Html的修改版本,您自己支持其他属性要容易得多。

在解析XML时,当遇到字体打开标记时,所有字体属性值都存储在Font私有类中。当遇到字体关闭标记时,对于这些属性中的每一个,应用相应的跨度样式。

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

附言:由于Html构造函数是私有的,因此不可能专门化Html

不幸的是,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");

相关内容

  • 没有找到相关文章

最新更新