ImageSpan on EditText (emoticons). Doesn't work with SwiftKey Keyboard

I am making a simple chat application and I want to show emoticons on edittext when writing a message.

I have this to identify that characters will be replaced by Image throught ImageSpan (this is only called when an emoticon character is inserted in the 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 use the SPAN_EXCLUSIVE_EXCLUSIVE tag to set the range, but I have problems with the swiftkey keyboard, because when I insert a smiley into the edittext, everything that I write immediately after imageSpan is held below the image (for example, SPAN_EXCLUSIVE_INCLUSIVE). With the default Android keyboard, I don't have this problem.

I just want the whatsapp application to perform the same behavior using emoticons in EditText.

Any suggestions? Any change I have to make with my code?

EDIT: the variable "editable" is passed to the method. This is the value of txtMessage.getText (), where txtMessage is an EditText.

Thanks!

EDIT: Use only one piece of code! This works well in multi-line mode! I think the problem was 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; } 
+6
source share
4 answers

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; } 
+13
source

You only need to create a spannable text using ImageSpan, and then setText Spannable to TextView or EditText as CommonsWare suggested in this post . You can also try using solution A-IV :

 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; } 
+4
source

Try this way, hope it helps you solve your problem.

  private static LinkedHashMap<String,Integer> emojisHashMap; public static LinkedHashMap<String, Integer> getEmojisHashMap() { if (emojisHashMap == null || emojisHashMap.size() == 0) { emojisHashMap = new LinkedHashMap<String, Integer>(); emojisHashMap.put(":=q", R.drawable.smiley1); emojisHashMap.put(":=w", R.drawable.smiley2); emojisHashMap.put(":=e", R.drawable.smiley3); emojisHashMap.put(":=r", R.drawable.smiley4); return emojisHashMap; } else { return emojisHashMap; } } public Spannable getSmiledText(CharSequence text) { SpannableStringBuilder builder; try { builder = (SpannableStringBuilder) text; }catch (Exception e){ builder = new SpannableStringBuilder(text); } if (getEmojisHashMap().size() > 0) { int index; for (index = 0; index < builder.length(); index++) { if (Character.toString(builder.charAt(index)).equals(":")) { for (Map.Entry<String, Integer> entry : getEmojisHashMap().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(getContext(), entry.getValue()), index, index + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); index += length - 1; break; } } } } } return builder; } 
0
source

In the XML file of emoticons, the "Image" button

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#dddddd" android:padding="10dp" > <ImageButton android:id="@+id/btn_smile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_smile" /> <ImageButton android:id="@+id/btn_kiss" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_kiss" /> <ImageButton android:id="@+id/btn_wink" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_wink" /> <ImageButton android:id="@+id/btn_cry" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_cry" /> <ImageButton android:id="@+id/btn_grumpy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_grumpy" /> <ImageButton android:id="@+id/btn_upset" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_upset" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#dddddd" android:padding="10dp" > <ImageButton android:id="@+id/btn_frown" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_frown" /> <ImageButton android:id="@+id/btn_tougn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_tounge" /> <ImageButton android:id="@+id/btn_grin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_grin" /> <ImageButton android:id="@+id/btn_gasp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_gasp" /> <ImageButton android:id="@+id/btn_glasses" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_glasses" /> <ImageButton android:id="@+id/btn_unsure" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@null" android:padding="10dp" android:src="@drawable/fb_unsure" /> </LinearLayout> </LinearLayout> 

// ================================================== ========

Enter this code in the dialog class

  private class SmileyMenu extends Dialog implements android.view.View.OnClickListener{ private Chat cht; Context con; public String MyStatus1=""; public SmileyMenu(Chat cht) { super(cht); this.con = cht; this.cht = cht; } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); setTitle("Select Smileys :"); setContentView(R.layout.smily_menu); ImageButton btnSmile = (ImageButton)findViewById(R.id.btn_smile); ImageButton btnkiss = (ImageButton)findViewById(R.id.btn_kiss); ImageButton btnwink = (ImageButton)findViewById(R.id.btn_wink); ImageButton btncry = (ImageButton)findViewById(R.id.btn_cry); ImageButton btngrupy = (ImageButton)findViewById(R.id.btn_grumpy); ImageButton btnupset = (ImageButton)findViewById(R.id.btn_upset); ImageButton btnfrown = (ImageButton)findViewById(R.id.btn_frown); ImageButton btngrin = (ImageButton)findViewById(R.id.btn_grin); ImageButton btngasp = (ImageButton)findViewById(R.id.btn_gasp); ImageButton btnglass = (ImageButton)findViewById(R.id.btn_glasses); ImageButton btnunsure = (ImageButton)findViewById(R.id.btn_unsure); ImageButton btndevil = (ImageButton)findViewById(R.id.btn_devil); ImageButton btnheart = (ImageButton)findViewById(R.id.btn_heart); ImageButton btnpacman = (ImageButton)findViewById(R.id.btn_pacman); ImageButton btn42 = (ImageButton)findViewById(R.id.btn_42); btnSmile.setOnClickListener(this); btnkiss.setOnClickListener(this); btnwink.setOnClickListener(this); btncry.setOnClickListener(this); btngrupy.setOnClickListener(this); btnupset.setOnClickListener(this); btnfrown.setOnClickListener(this); btngrin.setOnClickListener(this); btngasp.setOnClickListener(this); btnglass.setOnClickListener(this); btnunsure.setOnClickListener(this); btndevil.setOnClickListener(this); btnheart.setOnClickListener(this); btnpacman.setOnClickListener(this); btn42.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_smile: cht.setMyText(":-)"); break; case R.id.btn_kiss: cht.setMyText(":-*"); break; case R.id.btn_wink: cht.setMyText(";-)"); break; case R.id.btn_cry: cht.setMyText(":'("); break; case R.id.btn_grumpy: cht.setMyText(">:-("); break; case R.id.btn_upset: cht.setMyText(">:-O"); break; case R.id.btn_frown: cht.setMyText(":-("); break; case R.id.btn_tougn: cht.setMyText(":-p"); break; case R.id.btn_grin: cht.setMyText(":-D"); break; case R.id.btn_gasp: cht.setMyText(":-O"); break; case R.id.btn_glasses: cht.setMyText("8-)"); break; case R.id.btn_unsure: cht.setMyText(":-/"); break; case R.id.btn_devil: cht.setMyText("3:-)"); break; case R.id.btn_heart: cht.setMyText("<3"); break; case R.id.btn_pacman: cht.setMyText(":v"); break; case R.id.btn_42: cht.setMyText(":42:"); break; default: Toast.makeText(con, "Sorryyyyyy", Toast.LENGTH_SHORT).show(); break; } dismiss(); } } 

// ===================

Image of Click button for runtime emoticons menu

enter image description here

==================================================== ===

Try it, maybe it will help you .. Good luck ..

-1
source

Source: https://habr.com/ru/post/920527/


All Articles