How can I apply spans on EditText text when the user is composing?
For example the user has activated "bold" when composing, so every character input since then should be bold.
I thought about adding text change listener to the EditText and update the text as the user composes, but I wanna know if there's a better way of doing this.
The question was already answered in the comments, but to make it more permanent I will add a fuller answer.
In order to set a span (like Bold) wherever the user is composing, you just set a span on the text at the cursor (or selection) position.
StyleSpan boldSpan = new StyleSpan(Typeface.BOLD);
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
int flag = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
editText.getText().setSpan(boldSpan, start, end, flag);
The SPAN_INCLUSIVE_INCLUSIVE flag means that any text added before or after the span will be included in the span, even if the text length is 0 when the span is added.
See also
How to set other types of spans
Meaning of the Spannable flags
You can use the text watcher, and set the span in the editable that you receive in the afterTextChanged() method, I'm currently writing a rich text editor and this is the approach I've used with styles, and it works quite well, however, so far I haven't been able to set the spans that requires the paragraphs like quoteSpan, or bulletSpan.
But if you just want simple styles like italics, or bold etc., you can use this approach.
Related
What I'm actually doing is I'm storing a SpannableString in the form of HTML but it has a BackgroundColorSpan which has an aplha channel in its color. Now I got to know (via trials) that my aplha channel of the color goes away (due to inability of HTML) from the text whenever I try to store it.
Now what I want to know is that is there a way I can extract all the BackgroundColorSpan instances in the SpannableString AND change their color property? All the BackgroundColorSpan instances are of same color I just want to add an alpha channel to their color (by changing their color) before I present the text to users.
I figured out a way to extract all the BackgroundColorSpan instances by using getSpans but i still can't find a way to change their color.
Here's the related code:
SpannableString spannableDescString = new SpannableString(trimTrailingWhitespace(Html.fromHtml(note.getDesc())));
BackgroundColorSpan[] highlightSpanArray = spannableDescString.getSpans(0,spannableDescString.length(),BackgroundColorSpan.class);
if(highlightSpanArray.length!=0){
for(BackgroundColorSpan item : highlightSpanArray){
//what should I put here to change every item's color
}
}
desc.setText(spannableDescString);
Nevermind, I got the answer here
All I had to do was to delete the current span and replace it with the BackgroundColorSpan of the color that I required. Here's the code snippet.
SpannableString spannableDescString = new SpannableString(trimTrailingWhitespace(Html.fromHtml(note.getDesc())));
BackgroundColorSpan[] highlightSpanArray = spannableDescString.getSpans(0,spannableDescString.length(),BackgroundColorSpan.class);
if(highlightSpanArray.length!=0){
for(BackgroundColorSpan item : highlightSpanArray){
//what should i put here to change every items color
// get the span range
int start = spannableDescString.getSpanStart(item);
int end = spannableDescString.getSpanEnd(item);
// remove the undesired span
spannableDescString.removeSpan(item);
// set the new span with desired color
spannableDescString.setSpan(new BackgroundColorSpan(Color.RED),start,end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
desc.setText(spannableDescString);
I simply didn't know if I could find the starting and ending of individual spans.
All in the title.
Is it a bug or a desired behaviour ?
And in the last case, i can't understand why ?
Probably a bug or mutual exclusion.
When textAllCaps is set TextView applies TransformationMethod that takes the text and converting it to plain Strings that makes source text CharSequence loose all other stylings and spans.
You can trick it programatically like (Kotlin naive):
val text = textView.text // at this point allCaps is applied so text is caps
textView.setAllCaps(false) // remove the allCaps
val spannable = SpannableString(text) // create new spannable with allCapped text
spannable.setSpan(RelativeSizeSpan(1f), 0, text.length, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE)
textView.text = spannable //set it.
Another approach is creating your own TransformationMethod that will apply your Span for every text that is set.
I've searched something around here but nothing came up.
I'd like to have an EditText in which I can change attributes like color or dimension of a selected part.
I've already tried with the spannable thing, from another question:
TextView myTV = (TextView)findViewById(R.id.test);
String textString = "StackOverFlow Rocks!!!";
Spannable spanText = Spannable.Factory.getInstance().newSpannable(textString);
spanText.setSpan(new BackgroundColorSpan(0xFFFFFF00), 14, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
myTV.setText(spanText);
I assume that I have to assign it to some onClick method..Also my problems are those two number, I should put some "selectedText" there instead I think.
Is this even possible?
I'd like to have an EditText in which I can change attributes like color or dimension of a selected part
If you want the user to "change attributes... of a selected part", my recently-updated RichEditText offers that. I do not have color or text size going yet, though, as those will need a toolbar (rather than my current action mode support).
Also my problems are those two number, I should put some "selectedText" there instead I think
You are probably looking for getSelectionStart() and getSelectionEnd().
I have a edittext and some buttons like bold italics underline bullets. Now when i select some text and press any button then using spannable string i am applying that particular span to that portion of the edittext like bold italics underline etc.
I am trying to put Bulletspan in edittext. Here is the code i use to put bullet span:-
s.setSpan(new BulletSpan(), text.getSelectionStart(), text.getSelectionEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
where text is my reference to the Edittext.
Now the issue is that I want that my bulleted text should come at some leading margin space or indentation from start like it comes in any text editor like MS Word.
Just tell BulletSpan how much leading space you want. This example would give you 16dp leading space on the first and subsequent lines (like in the text editors you mentioned).
new BulletSpan(16);
Is it possible to set alignment on a single line or some lines in multiline edittext android?
If yes, then how, if no, then why not?
I get this answer from another question posted under the similar topic
"You can't apply multiple alignments within the same editText control. You'd have to solve your problem with some kind of manual padding of the text content"
So how can manual padding be inserted for selected lines?
you can use Alignment span to set alignment for a single line and multiple lines in multiline EditText provided you know the start and end index for the line. For example:
SpannableStringBuilder s = new SpannableStringBuilder("some text ");
AlignmentSpan span = new AlignmentSpan.Standard(Alignment.ALIGN_OPPOSITE);
s.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
t.setText(s);
You can apply alignment to multiple lines at once by covering multiple line between start and end index.