I use the same title with this question, because I think my question is very similar to that one, I read and tested the accepted answer very carefully, however the accepted answer doesn't work for me. Let me describe my question:
My code looks like:
EditText myEdit = (EditText) this.findViewById(R.id.myedit);
myEdit.setText("a\nb\n");
Spannable s = myEdit.getText();
s.setSpan(new BulletSpan(30), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
s.setSpan(new BulletSpan(30), 2, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
s.setSpan(new BulletSpan(30), 4, 4, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
myEdit.setText(s);
What I want to see is:
a
b
[I want to see the 3rd bullet here, but it doesn't show up]
I tried Spannable.SPAN_INCLUSIVE_INCLUSIVE, Spannable.SPAN_INCLUSIVE_EXCLUSIVE, Spannable.SPAN_EXCLUSIVE_INCLUSIVE,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE, but none of these flags works for me.
And if I use these codes:
EditText myEdit = (EditText) this.findViewById(R.id.myedit);
myEdit.setText("a\nb\nc");
Spannable s = myEdit.getText();
s.setSpan(new BulletSpan(30), 0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new BulletSpan(30), 2, 3, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
s.setSpan(new BulletSpan(30), 4, 5, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
myEdit.setText(s);
Then I get the expected result:
a
b
c
I am working on a rich text editor, when user clicks bullet icon, I need to show an empty bullet, but now I am not sure what the problem might be, as I want to make a new empty BulletSpan (with only a dot, but no chars after it), but if there are no chars in the span's start and end, the dot doesn't show up.
It is an ugly solution, but I have not found any better - try adding an empty character in the end (something like zero-width space). This is producing the result you'd like (at least visually):
public void setBulletText(EditText myEdit, String text) {
String[] lines = TextUtils.split(text, "\n");
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
String line = null;
for (int index = 0; index < lines.length; ++index) {
line = lines[index];
int length = spannableStringBuilder.length();
spannableStringBuilder.append(line);
if (index != lines.length - 1) {
spannableStringBuilder.append("\n");
} else if (TextUtils.isEmpty(line)) {
spannableStringBuilder.append("\u200B");
}
spannableStringBuilder.setSpan(new BulletSpan(30), length, length + 1,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
myEdit.setText(spannableStringBuilder);
}
The result is:
Ideally I'd make a custom EditText class which appends this character internally, but removes it when the text is being sent to any other object.
Is this good?
EditText myEdit = (EditText) this.findViewById(R.id.myedit);
myEdit.setText("a\nb\n\n");
Spannable s = myEdit.getText();
s.setSpan(new BulletSpan(30), 0, 1, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
s.setSpan(new BulletSpan(30), 2, 3, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
s.setSpan(new BulletSpan(30), 4, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
myEdit.setText(s);
myEdit.setSelection(s.length()-1);
The result is
I have a simple solution to this, just add a space at the end of the newline
EditText myEdit = (EditText) this.findViewById(R.id.myedit);
myEdit.setText("a\nb\n "); //notice the space after newline
Spannable s = myEdit.getText();
s.setSpan(new BulletSpan(30), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
s.setSpan(new BulletSpan(30), 2, 3, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
s.setSpan(new BulletSpan(30), 4, 4, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
myEdit.setText(s);
Related
I have a dictionary database for an offline dictionary and I need to format the definitions.
The dictionary is in Romanian so you won't understand too much from the definition but I will try to explain the format briefly.
definition example: #ABAGERÍE^2# #s. f.# Meseria de abagiu. - #Abager# + #suf.# $-ie.$
From the online version, I could discover some things
# = italic
^ = upperscript
"#" = bold
$ = underline
Is there any way how can I make this possible in android?
You can use the spannable style classes:
final SpannableStringBuilder sb = new SpannableStringBuilder("Hello World 123456");
sb.setSpan(new StyleSpan(Typeface.BOLD), 0, 7, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new StyleSpan(Typeface.ITALIC), 7, 14, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new ForegroundColorSpan(), 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(new UnderlineSpan(), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(new SuperscriptSpan(), 1, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(sb);
Follow the link to get the full list of ParcelableSpan subclasses:
https://developer.android.com/reference/android/text/ParcelableSpan
I am trying to print a decimal number inside a textview with a special format: the part on the left of the comma in one particular size and the part on the right in a different size.
Any idea about how can I make this work?
you can make use of SpannableString
TextView tv = findViewById(R.id.textview);
String value = "10.3";
final SpannableString text = new SpannableString(value);
text.setSpan(new RelativeSizeSpan(1.5f), value.indexOf(".")+1, value.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new ForegroundColorSpan(Color.RED), value.indexOf(".")+1, value.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(text);
for more refer these
http://alexandroid.net/spannablestring-example/
https://developer.android.com/reference/android/text/SpannableString.html
https://takeoffandroid.com/android-spannable-text-view-to-change-color-size-style-and-adding-click-event-for-particular-word-8acd8a05ec61
Use SpannableString..
Example
String yourText = "20.00";
SpannableString ss = new SpannableString(yourText);
ss.setSpan(new RelativeSizeSpan(1.2f), youString.indexOf(".") + 1, youString.length(), 0);
yourTextview.setText(ss);
Here is an example doing this
double number = 422.343;
String completeNumber = String.valueOf(number);
int decimalPointIndex = completeNumber.indexOf('.');
SpannableString ss= new SpannableString(completeNumber);
ss.setSpan(new RelativeSizeSpan(2f), 0,decimalPointIndex, 0);
textView.setText(ss);
Convert the decimal number to String
Get index value of decimal point
Then use it and display the first part before decimal as bigger
I know how to take substring a normal string.
But how can I substring a spannable.
Consider following example.
This is my sample sentence.
now when I substring this i want to get the string "mple sente" just like this and with all this formatings.
In another words I want to substring a spannable not a string.
How can I do this?
Spannable is a CharSequence and you should be able to use CharSequence.subSequence(int start, int end) without losing any information about the spannable
Using below code you can get substring from spannable:
SpannableString ss1 = new SpannableString(s);
ss1.setSpan(new RelativeSizeSpan(1.1f), 0, 6, 0); // set size
ss1.setSpan(new ForegroundColorSpan(Color.RED), 0, 6, 0);
SpannableString ss = new SpannableString("Click here to learn more");
ss.setSpan(clickableSpan, 0, 10, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textview.setText(ss);
Hope it helps you.
Say I have a SpannableString that a URLSpan is set for span in it like this:
SpannableString ss = new SpannableString(text);
ss.setSpan(new URLSpan("com://my.app"), 3, 6,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
Then I set another URLSpan for that span.But second URLSpan does not work and first one works.I can not use ss.removeSpan(what); because I do not want to remove all URLSpans.How I can solve this problem?
I use getSpans() in specific span(That I want to reset for it) to get it's span and then I use removeSpan to remove it:
SpannableString ss = new SpannableString(text);
ss.setSpan(new URLSpan("com://my.app"), 3, 6,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
URLSpan[] toRemoveSpans = ss.getSpans(3, 6, URLSpan.class);
ss.removeSpan(toRemoveSpans[0]);
ss.setSpan(new MyURLSpan("com://my.app"), 3, 6,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
I am trying to construct a SpannableString such that it looks like this:
Two characters (m, s) should be smaller than the rest.
I have tried to hold all the text in one SpannableString, and I also tried to concatenate two SpannableStrings via a SpannableStringBuilder.
The code for one Spannable looks like this:
spannable.setSpan(new RelativeSizeSpan(0.75f), spannable.length() - 1, spannable.length(), 0);
However, only one formatting is applied - when using the SpannableStringBuilder, only the "m" is smaller, and when using one SpannableString for the whole text, only the "s" is smaller.
Debugging also showed that Spannables seem to hold only one instance of RelativeSizeSpan, meaning there can be only one Span of one type. Is this true or expected behaviour?
Would it be advisable to concatenate TextViews instead?
EDIT: By the way, I am trying to remove a HTML.fromHtml() call here for performance reasons (many GC calls).
If you're still looking for an answer, I might have a solution. I had similar problems. I used TextUtils to concat the 2 SpannableString.
Here is some example code:
SpannableString span1 = new SpannableString("32m");
SpannableString span2 = new SpannableString("50s");
span1.setSpan(new RelativeSizeSpan(0.75f), 2, 3, 0);
span2.setSpan(new RelativeSizeSpan(0.75f), 2, 3, 0);
mTextView.setText(TextUtils.concat(span1," " ,span2));
You don't need 2 separate SpannableString.
A shorter solution can be :
SpannableString span1 = new SpannableString("32m50s");
span1.setSpan(new RelativeSizeSpan(0.75f), 2, 3, 0);
span1.setSpan(new RelativeSizeSpan(0.75f), 5, 6, 0);
mTextView.setText(span1);
You can use array of SpannableString.
Like in this case:
TextView lblDescription=(TextView ) findViewById(R.id.lblDescription);
SpannableString[] finalString = new SpannableString[stringSplit.length];
lblDescription.setText(TextUtils.concat(finalString));
I have using dynamic version of gbero's answer in my project,
public void updateTime(TextView tv) {
Calendar calendar = Calendar.getInstance();
SpannableString span = new SpannableString(
calendar.get(Calendar.HOUR_OF_DAY) + "h" + calendar.get(Calendar.MINUTE) + "m");
span.setSpan(new RelativeSizeSpan(0.75f), 2, 3, 0);
span.setSpan(new RelativeSizeSpan(0.75f), 5, 6, 0);
tv.setText(span);
}