2012-07-15 22 views
6

Tôi đang thực hiện một ứng dụng trò chuyện đơn giản và tôi muốn hiển thị mặt cười trên edittext khi viết tin nhắn.ImageSpan trên EditText (mặt cười). Với Bàn phím SwiftKey không hoạt động

Tôi đã này để xác định nhân vật mà sẽ được subsituted bởi một hình ảnh Xuyên một ImageSpan (điều này được gọi là chỉ khi một nhân vật biểu tượng mặt cười được chèn vào 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; 
      } 

     } 

Tôi đang sử dụng thẻ SPAN_EXCLUSIVE_EXCLUSIVE để thiết lập span, nhưng tôi có vấn đề với bàn phím swiftkey bởi vì khi tôi chèn một smiley trong edittext, tất cả mọi thứ tôi viết ngay sau khi imageSpan nó giữ bên dưới hình ảnh (như SPAN_EXCLUSIVE_INCLUSIVE). Với bàn phím mặc định của Android, tôi đã gặp vấn đề này.

Tôi chỉ muốn ứng dụng whatsapp cùng một biểu tượng mặt cười màu trắng trên EditText.

Mọi đề xuất? Bất kỳ thay đổi nào tôi phải thực hiện với mã của mình?

EDIT: biến "có thể chỉnh sửa" được chuyển cho phương thức. Nó là giá trị txtMessage.getText() trong đó txtMessage là EditText.

Cảm ơn!

CHỈNH SỬA: Chỉ sử dụng một phần mã! Điều này làm việc tốt trong multiline! Tôi nghĩ rằng vấn đề là sử dụng 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; 
} 
+0

gửi lỗi này cho nhà phát triển và xem họ nói gì .. – Ronnie

Trả lời

13

Sử dụng này một ::

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; 
} 
+0

Yeeessss !!! Tôi có cùng một vấn đề với Swiftkey nhưng với phương pháp này bạn đã giải quyết vấn đề khác với từ kết thúc tốt đẹp trên các mục listview với mặt cười !!!! Bây giờ tôi chỉ phải cải thiện tốc độ di chuyển bởi vì tôi có 470 mặt cười! Bất kỳ gợi ý nào để cải thiện tốc độ cuộn? – Igor

+0

Tôi đã chỉnh sửa mã của bạn để chỉ span một phần của chuỗi.Tôi đã đăng nó trong tin nhắn đầu tiên – Igor

+0

tôi đang sử dụng chế độ xem Dialog cho Display Smileys .. tôi đã đặt câu trả lời mới với hình ảnh và mã. .. –

4

Bạn phải chỉ để xây dựng một văn bản Spannable sử dụng ImageSpan và sau đó setText các Spannable để TextView hoặc EditText như CommonsWare đề xuất trong post này. Bạn cũng có thể thử sử dụng A-IV's giải pháp:

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; 
    } 
+0

Tôi đã thử giải pháp này nhưng vấn đề của tôi là tôi làm điều đó mỗi khi tôi chèn một mặt cười trên EditText và tôi chỉ có thể thay đổi ký tự mới được chèn vào. Tôi phải chuyển sang phương thức txtMessage.getText() (Spannable) để tôi chỉ có thể thay đổi ký tự mới. Phương pháp bạn gửi là vô giá trị nếu tôi phải kiểm tra tất cả các ký tự mỗi lần tôi chèn một biểu tượng mặt cười. – Igor

+0

Tôi đã cố gắng đặt ImageSpan thành SpannableStringBuilder và kết quả giống nhau ... Với Bàn phím SwiftKey tôi không thể viết ngay sau ImageSpan vì tất cả các ký tự bị ẩn bởi ImageSpan .... :-( – Igor

-1

Trong XML file biểu tượng mặt cười đưa Nút hình ảnh

<?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> 

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

Trong Dialog Lớp đặt mã này

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

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

Ảnh của Khi Click vào nút cho menu cười khi chạy

enter image description here

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

Hãy thử điều này có thể giúp cho bạn .. Chúc may mắn ..

+0

Câu hỏi của tôi là cải thiện tốc độ xem danh sách thư, vì bộ điều hợp danh sách phải tìm biểu tượng mặt cười mỗi khi thông báo được hiển thị. Tôi đã triển khai một số loại bộ nhớ cache nhưng người dùng có thể thay đổi kích thước phông chữ trên cấu hình ứng dụng và tôi tính toán lại kích thước mặt cười để chúng có cùng chiều cao như văn bản. Dù sao cũng cảm ơn bạn! – Igor

0

Hãy thử cách này, hy vọng điều này sẽ giúp bạn giải quyết vấn đề của mình.

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