I am doing a simple chat application and i want to show smileys on edittext while writing the message.
I have this to identify wich characters will be subsituted by an Image throught an ImageSpan (this is called only when an smileys character is inserted on EditText):
for (index = start; index < start+num_chars; index++) {
if (index + 1 > editable.length())
continue;
if(emoticons.containsKey(editable.subSequence(index, index + 1).toString())){
int length=1;
Drawable drawable = context.getResources().getDrawable(emoticons.get(editable.subSequence(index, index + 1).toString()));
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
int size=Utils.GetDipsFromPixel(context, (int)(textSize*1.3));
Drawable d = new BitmapDrawable(Bitmap.createScaledBitmap(bitmap, size, size, true));
int dWidth = d.getIntrinsicWidth();
int dHeight = d.getIntrinsicHeight();
d.setBounds(0 , -dHeight, dWidth, 0);
ImageSpan span;
span = new ImageSpan(d,ImageSpan.ALIGN_BASELINE);
editable.setSpan(span, index, index + length,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
index += length - 1;
}
}
I am using SPAN_EXCLUSIVE_EXCLUSIVE tag to set the span, but i have problems with swiftkey keyboard because when i insert an smiley in the edittext, everything i write just after the imageSpan it keeps below the image (like SPAN_EXCLUSIVE_INCLUSIVE). With the Android default keyboard i havent this problem.
I only want whatsapp application same behaviour whit smileys on EditText.
Any suggestions? Any change i have to do to my code?
EDIT: "editable" variable is passed to the method. It is txtMessage.getText() value where txtMessage is an EditText.
Thanks!
EDIT: Only Span one portion of code! This works good in multiline! I think the problem was in using Drawable->Bitmap->ResizedBitmap->Drawable.
public static final HashMap<String, Integer> emoticons = new HashMap();
static {
emoticons.put("\ue415", R.drawable.e415);
emoticons.put("\ue056", R.drawable.e056);
emoticons.put("\ue057", R.drawable.e057);
...
public static Spannable getSmiledText(Context context, Spannable editable,
int start, int num_chars, float textSize) {
int index;
for (index = start; index < start + num_chars; index++) {
if (index + 1 > editable.length())
continue;
if (EmojiLayout.emoticons.containsKey(editable.subSequence(index,
index + 1).toString())) {
int length = 1;
Bitmap smiley = BitmapFactory.decodeResource(context.getResources(), ((Integer) EmojiLayout.emoticons.get(editable.subSequence(index,
index + 1).toString())));
int size = Utils.GetDipsFromPixel(context,
(int) (textSize * 1.37));
Bitmap scaledbmp=Bitmap.createScaledBitmap(
smiley, size, size, false);
ImageSpan span;
span = new ImageSpan(scaledbmp);
Log.d("EmojiLayout", "Index: " + String.valueOf(index) + "To: "
+ String.valueOf(index + length));
editable.setSpan(span, index, index + length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
index += length - 1;
}
}
return editable;
}
Use this one ::
public static CharSequence addSmileySpans(Context ch, CharSequence your_recieved_message)
{
//smilyRegexMap = new HashMap<Integer, String>();
private static final HashMap<String, Integer> smilyRegexMap = new HashMap<String, Integer>();
smilyRegexMap.put( ">:-\\(" , R.drawable.fb_grumpy);
smilyRegexMap.put( ">:\\(" , R.drawable.fb_grumpy);
smilyRegexMap.put( ">:-O" , R.drawable.fb_upset);
smilyRegexMap.put( ":-\\)" , R.drawable.fb_smile);
smilyRegexMap.put( ":\\)",R.drawable.fb_smile);
smilyRegexMap.put( ":-\\]" , R.drawable.fb_smile);
smilyRegexMap.put( ":-\\(", R.drawable.fb_frown);
System.out.println("==In Spannable Function..........");
SpannableStringBuilder builder = new SpannableStringBuilder(your_recieved_message);
System.out.println("==================Size of Smily : "+ smilyRegexMap.size());
@SuppressWarnings("rawtypes")
Iterator it = smilyRegexMap.entrySet().iterator();
while (it.hasNext()) {
@SuppressWarnings("rawtypes")
Map.Entry pairs = (Map.Entry) it.next();
Pattern mPattern = Pattern.compile((String) pairs.getKey(),Pattern.CASE_INSENSITIVE);
Matcher matcher = mPattern.matcher(your_recieved_message);
while (matcher.find()) {
Bitmap smiley = BitmapFactory.decodeResource(ch.getResources(), ((Integer) pairs.getValue()));
Object[] spans = builder.getSpans(matcher.start(), matcher.end(), ImageSpan.class);
if (spans == null || spans.length == 0) {
builder.setSpan(new ImageSpan(smiley), matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
return builder;
}
You have just to build a Spannable text using ImageSpan and then setText the Spannable to TextView or EditText as CommonsWare suggested in this post. You can also try to use A-IV's solution:
private static final HashMap<String, Integer> emoticons = new HashMap();
static {
emoticons.put(":*", R.drawable.emo_im_kiss);
emoticons.put(":-D", R.drawable.emo_im_glad);
emoticons.put(":)", R.drawable.emo_im_happy);
emoticons.put(":-(", R.drawable.emo_im_sad);
...
}
public static Spannable getSmiledText(Context context, String text) {
SpannableStringBuilder builder = new SpannableStringBuilder(text);
int index;
for (index = 0; index < builder.length(); index++) {
for (Entry<String, Integer> entry : emoticons.entrySet()) {
int length = entry.getKey().length();
if (index + length > builder.length())
continue;
if (builder.subSequence(index, index + length).toString().equals(entry.getKey())) {
builder.setSpan(new ImageSpan(context, entry.getValue()), index, index + length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
index += length - 1;
break;
}
}
}
return builder;
}
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