我正在尝试将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>  a  <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()
非常有限,使用您的自定义文件格式将很快解决您的保存/恢复问题。
您需要在文件中存储以下信息:
-
的跨度有多少
-
每个跨度的开始、结束和颜色
-
您的文本
下面的代码片段显示了如何实现存储和加载方法。它使用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
的当前实现仅支持Font
的color
和typeface
属性。你可以在这里查看同样的内容。
正如您所说的,您使用的是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>  a  <font color ="#04ff00"><b><font style = "background-color:#2929dd">String</font></b></font>... </p>n";
webView.loadData(strGetData, "text/html", "utf-8");