Hello Everyone I am making an app where the user can italicize spannable text on a button click.
// Captures Contextual Menu Clicks//
public void onContextualMenuItemClicked(MenuItem item) {
int id = item.getItemId();
if (id == R.id.bold) {
// do some stuff
}
if (id == R.id.italic) {
int startSelection = noteContent.getSelectionStart();
int endSelection = noteContent.getSelectionEnd();
Spannable spannable = noteContent.getText();
spannable.setSpan(new StyleSpan(Typeface.ITALIC) , startSelection , endSelection , 0);
StyleSpanRemover spanRemover = new StyleSpanRemover();
spanRemover.RemoveStyle(spannable,startSelection,endSelection,Typeface.ITALIC);
}
this code makes it italic
int startSelection = noteContent.getSelectionStart();
int endSelection = noteContent.getSelectionEnd();
Spannable spannable = noteContent.getText();
spannable.setSpan(new StyleSpan(Typeface.ITALIC) , startSelection , endSelection , 0);
This makes it un-italic
StyleSpanRemover spanRemover = new StyleSpanRemover();
spanRemover.RemoveStyle(spannable,startSelection,endSelection,Typeface.ITALIC
I want the user to click the same button to italicize and un-italicize. What if statment can I use to get what TypeFace the spannable selected words are? That way it knows if to italicize or not
UPDATE: this is what I have now
int startSelection = noteContent.getSelectionStart();
int endSelection = noteContent.getSelectionEnd();
Spannable spannable = noteContent.getText();
StyleSpan[] spans = spannable.getSpans(startSelection, endSelection, StyleSpan.class);
if (spans.length == 0) {
spannable.setSpan(new StyleSpan(Typeface.ITALIC), startSelection, endSelection , 0);
} else {
spannable.setSpan(new StyleSpan(Typeface.NORMAL), startSelection, endSelection , 0);
}
even though the code runs the code
spannable.setSpan(new StyleSpan(Typeface.NORMAL), startSelection, endSelection , 0);
and sets it back to normal. but it wont set spans.length back to zero so I cant italicize it again how to i set spans.length to zero.
You can use getSpans(startSelection, endSelection, StyleSpan.class) to see what spans are present in the selection range. Based on that, you can decide whether (and how) to italicize the text. Note the user might highlight a portion that contains both normal text and italicized text.
EDIT
StyleSpan[] spans = spannable.getSpans(startSelection, endSelection, StyleSpan.class);
if (spans.length == 0) {
// no spans, italicize text here
} else {
// TODO
}
Related
I'm trying to change the background color of a specific text e.g. this is the text xxxx 0 visible and I want to change background color of 0.
Here is my code
private TextView setTVBenutzername(View view, Question question, int groupPosition) {
String BenutzerName = question.Benutzername;
TextView textView = (TextView) view.findViewById(R.id.txtBenutzername);
textView.setTag(groupPosition);
textView.setOnClickListener(this.onGroupClickListenerAll);
textView.setOnLongClickListener(this.onGroupClickListener);
Integer Bewertungen;
Bewertungen = question.Bewertungen;
if (Bewertungen != null) BenutzerName += " " + Bewertungen + "";
BenutzerName += " " + question.onlineState.getStateString();
textView.setText(BenutzerName);
final Spannable spannable = new SpannableString(textView.getText().toString());
// Setting Foreground color to the entire text to red
spannable.setSpan(new ForegroundColorSpan(Color.RED),
0, textView.getText().toString().length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Getting the indices of the number (Bewertungen)
Matcher matcher = Pattern.compile("\\d+").matcher(textView.getText().toString());
matcher.find();
int startIndex = matcher.start();
int endIndex = matcher.end();
if (question.online && question.onlineState.state > MainActivity.OnlineState.invisible.state) {
// Setting Foreground color
spannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.colorUserOnline)),
startIndex, endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannable);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_online, 0);
} else {
// Setting Foreground color
spannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.colorUser)),
startIndex, endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannable);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
return textView;
}
App crash when I run.
Error is
java.lang.IllegalStateException: No successful match so far
at java.util.regex.Matcher.ensureMatch(Matcher.java:1116)
at java.util.regex.Matcher.start(Matcher.java:1158)
at java.util.regex.Matcher.start(Matcher.java:1130)
at de.com.limto.limto1.Controls.QuestionsAdapter.setTVBenutzername(QuestionsAdapter.java:1645)
at de.com.limto.limto1.Controls.QuestionsAdapter.setGroupView(QuestionsAdapter.java:1203)
at de.com.limto.limto1.Controls.QuestionsAdapter.getGroupView(QuestionsAdapter.java:1156)
at android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:446)
find() method returns a Boolean indicating whether a match has found or not, and without match you cannot get the index, so wrap inside if condition, like below
if(matcher.find()){
int startIndex = matcher.start();
int endIndex = matcher.end();
if (question.online && question.onlineState.state > MainActivity.OnlineState.invisible.state) {
// Setting Foreground color
spannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.colorUserOnline)),
startIndex, endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannable);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_online, 0);
} else {
// Setting Foreground color
spannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.colorUser)),
startIndex, endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannable);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
}
I am developing an simple text editor in android with few basic options like bold, italic, bold+italic, underline strike through. Here is the code that I've used for applying the effects to the selected text when the corresponding button is clicked.
public void buttonClick(View target){
Log.i("Information ", "In click");
View parentView = (View) target.getParent();
final EditText editorField = (EditText) parentView.findViewById(R.id.editor_field);
int startSelection = editorField.getSelectionStart();
int endSelection = editorField.getSelectionEnd();
Spannable textEdit = editorField.getText();
if(target.getId() == R.id.boldButton){
textEdit.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), startSelection, endSelection, 0);
} else if(target.getId() == R.id.italicButton){
textEdit.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), startSelection, endSelection, 0);
} else if(target.getId() == R.id.underlineButton){
textEdit.setSpan(new UnderlineSpan(), startSelection, endSelection, Spannable.SPAN_MARK_MARK);
} else if(target.getId() == R.id.strikeButton){
textEdit.setSpan(new StrikethroughSpan(), startSelection, endSelection, Spannable.SPAN_MARK_MARK);
} else if(target.getId() == R.id.boldItalicButton){
textEdit.setSpan(new StyleSpan(android.graphics.Typeface.BOLD_ITALIC), startSelection, endSelection, 0);
}
}
But before applying the text effect I have to check whether the selected text already have any text effect or not. i.e. Initially the selected text is in bold, so when bold button is clicked then that text effect must be removed. I don't understand how to do this. Could any one help me.
Regards.
You can get the list of styles calling the getSpans() method:
StyleSpan[] styleSpans = textEdit.getSpans(startSelection, endSelection, StyleSpan.class);
And then use the methods of the StyleSpan class:
if (styleSpans[i].getStyle() == android.graphics.Typeface.BOLD){
...
}
I am using this code to remove formatting of a spannable text from start till end. The problem is that it is working successfully, but the last character in the text is still bold (or italics/underline).
removeSpan is not working on the last character in the text:
int startSelection = 0;
int endSelection = text.length();
if(startSelection > endSelection) {
startSelection = text.getSelectionEnd();
endSelection = text.getSelectionStart();
}
Spannable str = text.getText();
StyleSpan[] ss = str.getSpans(startSelection, endSelection, StyleSpan.class);
for (int i = 0; i < ss.length; i++) {
if (ss[i].getStyle() == android.graphics.Typeface.BOLD) {
str.removeSpan(ss[i]);
}
if (ss[i].getStyle() == android.graphics.Typeface.ITALIC) {
str.removeSpan(ss[i]);
}
}
UnderlineSpan[] ulSpan = str.getSpans(startSelection, endSelection, UnderlineSpan.class);
for (int i = 0; i < ulSpan.length; i++) {
str.removeSpan(ulSpan[i]);
}
str.removeSpan(ss[1]);
text.setText(str);
If you want remove all spans from text use this:
Spannable str = text.getText();
Object spansToRemove[] = str.getSpans(startSelection, endSelection, Object.class);
for(Object span: spansToRemove){
if(span instanceof CharacterStyle)
spannable.removeSpan(span);
}
There is a very simple solution:
When you set the Spannable object to a TextView you use myTextView.setText(spannable); this adds your custom formatting of you assigned to the spannable.
In order to clear all the spans at once from the TextView use: myTextView.setText(spannable.toString());
Example
Spannable spannable = new SpannableString(myTextView.getText().toString());
spannable.setSpan(new ForegroundColorSpan(Color.RED), 8, 13,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, 30, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new BackgroundColorSpan(Color.BLUE), 10, 20, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new UnderlineSpan(), 7, 11, 0);
myTextView.setText(spannable); // add all the spannable format
myTextView.setText(spannable.toString()); // clear all the spannable format
The following works for me (given that "text" is your TextView or EditText):
String str = text.getText().toString();
text.setText(str);
I changed the code a little bit. Have a look. I have removed the if conditions inside the loop. It is working now.
fromSelectionSpan = true;
int startSelection = 0;
int endSelection = text.length();
Spannable str = text.getText();
StyleSpan[] ss = str.getSpans(startSelection, endSelection, StyleSpan.class);
for (int i = 0; i < ss.length; i++) {
str.removeSpan(ss[i]);
}
UnderlineSpan[] ulSpan = str.getSpans(startSelection, endSelection, UnderlineSpan.class);
for (int i = 0; i < ulSpan.length; i++) {
str.removeSpan(ulSpan[i]);
}
text.setText(str);
b.setChecked(false);
i.setChecked(false);
u.setChecked(false);
text.setSelection(endSelection);
Here's a small utility method I created as an extension to TextView, tested in API 29:
fun TextView.removeAttributedProperties (forText: String? = null) {
forText?.let {
// check if the text we're highlighting is empty to abort
if (forText.isEmpty()) {
return
}
// compute the start and end indices from the text
val startIdx = text.indexOf(forText)
val endIdx = startIdx + forText.length
// if the indices are out of bounds, abort as well
if (startIdx < 0 || endIdx > text.length) {
return
}
(text as? SpannedString)?.let { spannedString ->
val spannable = spannedString.toSpannable()
val spansToRemove = spannable.getSpans(startIdx, endIdx, CharacterStyle::class.java)
for (span in spansToRemove) {
spannable.removeSpan(span)
}
// update the text back
text = spannable
}
} ?: run {
// if we have no text, let's remove all attributed properties
text = text.toString()
}
}
Simple, re-initiate your SpannableString.
Hope this will save your time.
I have an EditText, and can add formatting such as bold, italic....but how can I remove it? I've looked into getSpans, filters, and other non-string things and haven't been able to make sense of them! Ideally, I'd like to be able to clear specific tags and all tags set around the selected text.
Update with my solution:
private String getSelectedText(){
int start = Math.max(mText.getSelectionStart(), 0);
int end = Math.max(mText.getSelectionEnd(), 0);
return mText.getText().toString().substring(Math.min(start, end), Math.max(start, end));
}
private void clearFormat(){
int s1 = Math.max(mText.getSelectionStart(), 0);
int s2 = Math.max(mText.getSelectionEnd(), 0);
String text = getSelectedText(); if(text==""){ return; }
EditText prose = mText;
Spannable raw = new SpannableString(prose.getText());
CharacterStyle[] spans = raw.getSpans(s1, s2, CharacterStyle.class);
for (CharacterStyle span : spans) {
raw.removeSpan(span);
}
prose.setText(raw);
//Re-select
mText.setSelection(Math.min(s1,s2), Math.max(s1, s2));
}
but how can I remove it?
Call removeSpan() on the Spannable.
For example, this method from this sample project searches for a search string in the contents of a TextView and assigns it a background color, but only after removing any previous background colors:
private void searchFor(String text) {
TextView prose=(TextView)findViewById(R.id.prose);
Spannable raw=new SpannableString(prose.getText());
BackgroundColorSpan[] spans=raw.getSpans(0,
raw.length(),
BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
raw.removeSpan(span);
}
int index=TextUtils.indexOf(raw, text);
while (index >= 0) {
raw.setSpan(new BackgroundColorSpan(0xFF8B008B), index, index
+ text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index=TextUtils.indexOf(raw, text, index + text.length());
}
prose.setText(raw);
}
}
what you could try is:
1- Create a custom style where your EditText will have "such as bold, italic..."
2- Be aware of using R.style.normalText to change it back to it's normal style at runtime
3- Change this styles depending on the behaviour you want to achieve via setTextAppearance(Context context, int resid)
Here is an example i found googling How to change a TextView's style at runtime
Edit: as your question is "How to clear formatting from an EditText" here is the specific answer as code:
editTextToClearStyle.setTextAppearance(this,R.style.normalText);
Please see the comment of the snippet below.
if (makeItalic) {
SpannableString spanString = new SpannableString(textViewDescription.getText());
spanString.setSpan(new StyleSpan(Typeface.ITALIC), 0, spanString.length(), 0);
this.textViewDescription.setText(spanString);
} else {
SpannableString spanString = new SpannableString(
textViewDescription.getText().toString()); // NOTE: call 'toString()' here!
spanString.setSpan(new StyleSpan(Typeface.NORMAL), 0, spanString.length(), 0);
this.textViewDescription.setText(spanString);
}
... just get the raw string characters by calling the toString() method.
Is there possibility in android to provide TextView some text in Java code with setText(text) function with basic tags like and to make marked words underlined ?
Yes, you can, use the Html.fromhtml() method:
textView.setText(Html.fromHtml("this is <u>underlined</u> text"));
Define a string as:
<resources>
<string name="your_string">This is an <u>underline</u> text demo for TextView.</string>
</resources>
You can use UnderlineSpan from SpannableString class:
SpannableString content = new SpannableString(<your text>);
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
Then just use textView.setText(content);
tobeunderlined= <u>some text here which is to be underlined</u>
textView.setText(Html.fromHtml("some string"+tobeunderlined+"somestring"));
Most Easy Way
TextView tv = findViewById(R.id.tv);
tv.setText("some text");
setUnderLineText(tv, "some");
Also support TextView childs like EditText, Button, Checkbox
public void setUnderLineText(TextView tv, String textToUnderLine) {
String tvt = tv.getText().toString();
int ofe = tvt.indexOf(textToUnderLine, 0);
UnderlineSpan underlineSpan = new UnderlineSpan();
SpannableString wordToSpan = new SpannableString(tv.getText());
for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
ofe = tvt.indexOf(textToUnderLine, ofs);
if (ofe == -1)
break;
else {
wordToSpan.setSpan(underlineSpan, ofe, ofe + textToUnderLine.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
}
}
}
If you want
- Clickable underline text?
- Underline multiple parts of TextView?
Then Check This Answer