android No successful match so far - android

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);
}
}

Related

set background for only a part of TextView

For example, I have a textview (multi line): aaaaaaaaabbbbaaa. I want to set background for only 'bbb' characters. I try to use Spannable but it doesn't work with my background is a image from drawable.
Many thanks.
using BackgroundColorSpan you can do that ,but Chinese doesn`t work in right way .
private void replaceText(TextView text, String str, int color) {
Spannable raw = new SpannableString(text.getText());
BackgroundColorSpan[] spans = raw.getSpans(0,raw.length(),BackgroundColorSpan.class);
for (BackgroundColorSpan span : spans) {
raw.removeSpan(span);
}
int index = TextUtils.indexOf(raw, str);
while (index >= 0) {
raw.setSpan(new BackgroundColorSpan(color), index, index + str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index = TextUtils.indexOf(raw, str, index + str.length());
}
text.setText(raw);
}
private fun highlightTextPart(
textView: TextView,
mainString: String,
subString: String
) {
if (mainString.contains(subString)) {
val startIndex = mainString.indexOf(subString)
val endIndex = startIndex + subString.length
val spannableString = SpannableString(mainString)
spannableString.setSpan(
BackgroundColorSpan(Color.parseColor("#ff00ff")),
startIndex,
endIndex,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
textView.text = spannableString
}
}
using
highlightTextPart("text text sell text", textView, "sell");

Android - Using SpannableStringBuilder for per character color change

Heyo, I'm using SpannableStringBuilder to change a word's each character color. This is how I use it :
SpannableStringBuilder specialSpan = new SpannableStringBuilder();
specialSpan.append(context.getResources().getString(R.string.asdf));
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.blue)), 0, 0, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.purple)), 1, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.orange)), 2, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.green)), 3, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
userSpecialText.setText(specialSpan);
The problem is, the TextView's color doesn't change. Am I missing something here?
Update :
I'm using this other Spannable string builder which works for adding Emojis
for (String part :
partofContent){
if (part.contains(":")){
int firstEq = sb.length();
Typeface font = FontCache.getTypeface("emojione-android.ttf", context);
String convertPart = Emojione.shortnameToUnicode(part, true);
sb.append(convertPart + " ");
int lastEq = sb.length();
sb.setSpan(new CustomTypefaceSpan("", font), firstEq, lastEq, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
sb.append(part + " ");
}
}
And to change the color of a detected user Alias
int aliasStart = sb.length();
sb.append("#" + alias + " ");
int aliasEnd = sb.length();
sb.setSpan(new MyClickableSpan("#" + alias + " "), aliasStart, aliasEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.miBlue)), aliasStart, aliasEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
sb.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), aliasStart, aliasEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
That worked well too, and it uses the same ForegroundColorSpan in setSpan().
Try like This
SpannableStringBuilder specialSpan = new SpannableStringBuilder();
specialSpan.append(context.getResources().getString(R.string.asdf));
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.blue)), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.purple)), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.orange)), 2, 3, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
specialSpan.setSpan(new ForegroundColorSpan(context.getResources().getColor(R.color.green)), 3, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
userSpecialText.setText(specialSpan);
You're specifing same for both start and end that means you're specifying a span of length 0, not a span of length 1.

Toggle edit text Typeface

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
}

AbsoluteSizeSpan working slow in EditText in Android

I am making an app consisting of EditText in which the user can change the text size as well as color of text dynamically on entering text in EditText. I am able to change the color of current text in between previously entered text using span in customized InputFilter, but on changing text size in span inside a InputFilter, lag comes when entering text in between perviously entered text.
Here is my code for InputFilter:
class MyTextFilter implements InputFilter{
#Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try{
Spannable span = new SpannableString(source.subSequence(start, start + 1));
if(colorSelected.equalsIgnoreCase("red")){
span.setSpan(new ForegroundColorSpan(Color.RED), start, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(colorSelected.equalsIgnoreCase("green")){
span.setSpan(new ForegroundColorSpan(Color.GREEN), start, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(colorSelected.equalsIgnoreCase("blue")){
span.setSpan(new ForegroundColorSpan(Color.BLUE), start, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if(sizeSelected.equalsIgnoreCase("small")){
span.setSpan(new TextAppearanceSpan(null, 0, 10, null, null), start, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(sizeSelected.equalsIgnoreCase("medium")){
span.setSpan (new TextAppearanceSpan(null, 0, 20, null, null), start, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
else if(sizeSelected.equalsIgnoreCase("large")){
span.setSpan(new TextAppearanceSpan(null, 0, 30, null, null), start, start + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
// if(sizeSelected.equalsIgnoreCase("small")){
// span.setSpan(new AbsoluteSizeSpan(20), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
// else if(sizeSelected.equalsIgnoreCase("medium")){
// span.setSpan (new AbsoluteSizeSpan(60), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
// else if(sizeSelected.equalsIgnoreCase("large")){
// span.setSpan(new AbsoluteSizeSpan(80), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// }
Log.e("span", "="+span);
return span;
} catch(Exception e){
e.printStackTrace();
return null;
}
}
}
your approach is wrong, try to add the following in onCreate:
EditText et = new EditText(this);
et.setTextSize(30);
SpannableStringBuilder b = new SpannableStringBuilder("smallbsmall");
Object what = new AbsoluteSizeSpan(40);
b.setSpan(what, 5, 6, Spanned.SPAN_EXCLUSIVE_INCLUSIVE);
et.setText(b);
et.setSelection(6);
setContentView(et);
now the "cursor" is between big "b" and small "small" text, now type "i" and "g". you see what happens? now you have big "big", and you did nothing in your code - that's the way the spans work

How to clear formatting from an EditText?

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.

Categories

Resources