I am working on an application where the user can post content to a feed. In my edit text (used for composing) the text colour is grey. However when the user types a hash tag e.g. #help I need to colour that text black as they type, so when the user types '#' the text must be coloured black until they start a new word, then the text colour needs to revert to grey.
I have been trying using a text watcher and a spannable string to colour.
Here is what I have done with the textwatcher onTextChanged
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//Remove Text watcher to prevent infinite look
mTextField.removeTextChangedListener(contentFieldWatcher);
String startChar = null;
startChar = Character.toString(s.charAt(start));
L.i(getClass().getSimpleName(), "CHARACTER OF NEW WORD: " + startChar);
if (startChar.equals("#")) {
tagCheck(s.toString().substring(start), start, start + count);
}
}
tagCheck method
private void tagCheck(String s, int start, int end) {
mSpannable.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.black_colour)), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mSpannable is a Spannable.
The problem with this method is that '#' shows as startChar, however when the user types the next character, either symbol or letter, it then shows as startChar. Where as if the user typed santa - 's' remains the startChar. So the issue I'm facing his how to dynamically colour the text as the user types a hashtag.
So plain letters work correctly, however when you use a symbol it does not. I hope the question has clarity..I've been looking at this for a few days and it's all getting hazy :)
I tried and found the soloution
You can use following code
Spannable mspanable;
int hashTagIsComing = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText edt = (EditText) findViewById(R.id.editText1);
mspanable = edt.getText();
edt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String startChar = null;
try{
startChar = Character.toString(s.charAt(start));
Log.i(getClass().getSimpleName(), "CHARACTER OF NEW WORD: " + startChar);
}
catch(Exception ex){
startChar = " ";
}
if (startChar.equals("#")) {
tagCheck(s.toString().substring(start), start, start + count);
hashTagIsComing++;
}
if(startChar.equals(" ")){
hashTagIsComing = 0;
}
if(hashTagIsComing != 0) {
tagCheck(s.toString().substring(start), start, start + count);
hashTagIsComing++;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
}
private void tagCheck(String s, int start, int end) {
mspanable.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.color)), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
I managed to achieve the behavior you are describing, it's just that I am setting the colored text on a separate TextView. See the screenshot and code below. I hope this helps
In afterTextChanged of the listener:
@Override
public void afterTextChanged(Editable s) {
editText.removeTextChangedListener(textWatcher);
colorText(s.toString());
}
Method to find "#" characters and color text until first space:
private void colorText(String s) {
if (!TextUtils.isEmpty(s)) {
Spannable spannable = new SpannableString(s);
int position = 0;
position = s.indexOf("#", position);
while (position != -1) {
colorSpannable(spannable, position, s.indexOf(" ", position + 1) != -1 ? s.indexOf(" ", position + 1) : s.length());
position = s.indexOf("#", position + 1);
}
textView.setText(spannable);
}
editText.addTextChangedListener(textWatcher);
}
colorSpannable simply adds the color from index start to index end
private void colorSpannable(Spannable s, int start, int end){
s.setSpan(new ForegroundColorSpan(Color.BLUE), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With