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
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);
}
}
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.
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);
I'm trying to do an alternate coloring of each character of an input string using SpannableString's setSpan(), but somehow the outputted string is not colored properly.
//ColorLogic.java:
public SpannableString colorString(String myStr)
{
SpannableString spnStr=new SpannableString(myStr);
int strLen=myStr.length();
for(int i=0; i< strLen; i++)
{
if (i%2==0)
{
Log.v(DTAG, "vow"+myStr.charAt(i));
spnStr.setSpan(new ForegroundColorSpan(Color.RED), i, i, 0);
}
else
{
Log.v(DTAG, "cons"+myStr.charAt(i));
spnStr.setSpan(new ForegroundColorSpan(Color.BLUE), i, i, 0);
}
}
return spnStr;
}
//In my OnCreate of my activity class:
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(50);
//Call Color Logic to color each letter individually
ColorLogic myColorTxt=new ColorLogic();
SpannableString spnMsg=myColorTxt.colorString(message);
textView.setText(spnMsg, BufferType.SPANNABLE);
setContentView(textView);
}
output:
![2 letters][1]
[1]: http://i.stack.imgur.com/rA8TV.png
![3 letters][1]
[1]: http://i.stack.imgur.com/X039z.png
I have noticed that if I simply have :
spnStr.setSpan(new ForegroundColorSpan(Color.RED), 0, 0, 0);
Then ALL the characters of the string is colored red, even though I had specified the start and stop to be the 1st char. I've tried different Spannable flags such as: android.text.Spannable.SPAN_INCLUSIVE_INCLUSIVE
, but the same problem still occurs.
You're specifing i for both start and end - this means you're specifying a span of length 0, not a span of length 1. Try this:
spnStr.setSpan(new ForegroundColorSpan(Color.RED), i, i + 1, 0);
String aux = getInserzionista(offerta.getIdInserzionista());
sotto_titolo.setText("Offerta dal " + aux);
int inizio = 12;
int fine = 11+aux.length();
sotto_titolo.setMovementMethod(LinkMovementMethod.getInstance());
sotto_titolo.setText(sotto_titolo.getText().toString(),BufferType.SPANNABLE);
Spannable mySpannable = (Spannable) sotto_titolo.getText();
ClickableSpan myClickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
}
};
//if i put this, not work
mySpannable.setSpan(new ForegroundColorSpan(Color.RED), inizio, fine, 0);
mySpannable.setSpan(myClickableSpan, inizio, fine + 1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
But if i put this:
mySpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, 0);
It works, because the text from 0 to 4 is colored!
So, my question is:
How can I change the color of the link (the one colored blue and underlined)?
Thanks
because you set a static value 4 in this line mySpannable.setSpan(new ForegroundColorSpan(Color.RED), 0, 4, 0);. Set text length in place of 4.
Have you tried using updateDrawState()?