I am trying to set BackgroundColorSpan to selected text in my Edit-text. So when i select any text and click on button it will set Background color to that particular text and then i am saving that note to my SDCard with .html format and then again i am retrieving that note to edit again in the same format.
The problem i am facing right now is when i apply BackgroundColorSpan to selected text it show's that string with background color which i applied but once i save that note to my SDCard and re-open, it does not show Background color to that particular string instead of that it show me normal string without background color.
Below is my code Which i used to set Background Color to Edit-text selected area
mSpannable.setSpan(new BackgroundColorSpan(color),startSelection, endSelection, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
and below is code to save my notes to 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();
With this above code i am successfully able to save my file in HTML format, but i am not getting the string with Background color.
I tried to print that string in Log and then pasted that string in w3School then i get exact result what i expect it to be but in android i don't know why it is not working.
String which i get in Logcat is below
<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>
You can try this string here which gives perfect result with background color to string but while setting to android Edit-ext i don't know what is happening and it's not setting as i expect it to be.
Edit
Below is code which i used to retrieve text from my SDcard file
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);
The same Problem I faced while creating a project of saving the HTML notes.
As you said that you have made your customized HTML.java class I also customized the same class for my purpose.
The default Html.java class does not contain the functionality for backgroundcolor, font size, bullet etc.
So Here i am sharing the content of that class so you can get the idea from it to set the Backround Color to you HTML Note.
Let's assume your customized Html.java = AppHtml.java so other can understand it better.
1) First add the background color tag in your AppHtml.java class. Add this below code to your withinParagraph method.
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("\">");
}
then complete the font style that you have started
if (style[j] instanceof BackgroundColorSpan) {
out.append("</font>");
}
2) Here is my Font class
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) Here is my startFont method.
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) Here is my endFont method.
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);
}
}
}
}
I do not know what is AppHtml
in your source code but for Html<->Spannable parsing in Android we use android.text.Html
class. This class though doesn't support BackgroundColorSpan
for some reason.
I would suggest experimenting with Html.fromHtml(String source, Html.ImageGetter imageGetter, Html.TagHandler tagHandler)
method and pass a TagHandler
to support what you need. Docs are here.
I don't know whether this is exactly what you are looking for, but I don't see the point to use HTML here. As other answers pointed out, fromHtml()
is quite limited and using you custom file format will solve your saving / restoring problem in no time.
You need to store on a file the following pieces information:
How many spans you have
start, end, color for each span
your text
The following code snippet shows how to implement the store and load methods. It uses the Spanned
text in a TextView
. The complete Eclipse project took me about half an hour and can be found here.
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);
}
}
Current implementation of Html.fromHtml
only supports Font
's color
and typeface
attributes. You can check the same here.
As you said you are using modified version of Html
, it is much more easier to support additional attributes by yourself.
While parsing the XML, when font open tag is encountered, all the font attribute values are stored in Font
private class. When font close tag is encountered, for each of those attributes, apply corresponding span styles.
Step 1 : In Font
private class add a data member for holding the background color and modify the constructor to accept additional paramter.
private static class Font {
...
public String mBackgroundColor; // Data member to hold background color
public Font(String color, String face, String backgroundColor) {
...
mBackgroundColor = backgroundColor;
}
...
}
Step 2 : In startFont
method, handle the background-color
attribute.
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);
}
Step 3: In endFont
method, add the BackgroundColorSpan
to the text.
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. : Since Html
constructor is private, specializing the Html
is not possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With