1. 程式人生 > >Android開發筆記之傳送小表情的實現

Android開發筆記之傳送小表情的實現

本部落格主要實現的是像QQ表情的傳送以及文字與表情的一起傳送

我們首先要明白QQ表情的傳送其實是一種特別的文字,也是文字的形式,所以我們需要將QQ表情轉化為特殊的文字形式
第一步我們先做一個資源工具類,如下所示

//我們把表情資源做成一個工具類
public class EmoUtils {
    public static int[] face = new int[] { R.drawable.ee_1, R.drawable.ee_2,
            R.drawable.ee_3, R.drawable.ee_4, R.drawable.ee_5, R.drawable
.ee_6, R.drawable.ee_7, R.drawable.ee_8, R.drawable.ee_9, R.drawable.ee_10, R.drawable.ee_11, R.drawable.ee_12, R.drawable.ee_13, R.drawable.ee_14, R.drawable.ee_15, R.drawable.ee_16, R.drawable.ee_17, R.drawable.ee_18, R.drawable.ee_19, R.drawable
.ee_20, R.drawable.ee_21, R.drawable.ee_22, R.drawable.ee_23, R.drawable.ee_24, R.drawable.ee_25, R.drawable.ee_26, R.drawable.ee_27, R.drawable.ee_28, R.drawable.ee_29, R.drawable.ee_30, R.drawable.ee_31, R.drawable.ee_32, R.drawable.ee_33, R.drawable
.ee_34, R.drawable.ee_35, }; public static String[] face_name = new String[] { "ee_1", "ee_2", "ee_3", "ee_4", "ee_5", "ee_6", "ee_7", "ee_8", "ee_9", "ee_10", "ee_11", "ee_12", "ee_13", "ee_14", "ee_15", "ee_16", "ee_17", "ee_18", "ee_19", "ee_20", "ee_21", "ee_22", "ee_23", "ee_24", "ee_25", "ee_26", "ee_27", "ee_28", "ee_29", "ee_30", "ee_31", "ee_32", "ee_33", "ee_34", "ee_35" }; }

第二步我們做一個ImageUtils用來轉化表情,具體的程式碼如下

//在這裡對三個引數解釋一下,
//第一個引數為上下文
//第二引數為資源的名字,也就是圖片的真實名稱
    public static SpannableString getSpanableString(Context context, String name)
            throws Exception {
            //html圖片的識別符號
        String html = "<img src='" + name + "'/>";
//此出得到的是一個field檔案,也就是根據名字找到的資源Id檔案      
Field field =R.drawable.class.getDeclaredField(name);
//但是我們拿到的資源是一個string字串,需要包裝稱為一個資源ID
        int resourceId = Integer.parseInt(field.get(null).toString());
        //通過bitmapFactory工廠處理解碼,裝化成bitmap圖片
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
                resourceId);
    //要讓圖片替代指定的文字就要用ImageSpan
     ImageSpan imageSpan = new ImageSpan(context, bitmap);
        //此處是將html識別符號轉化為特殊文字,SpannnableString類就是這麼一個
SpannableString spannableString = new    不      SpannableString(html);//html就是圖片的字首名
spannableString.setSpan(imageSpan, 0,html.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannableString;
    }
  1. 由於R.drawable中的資源ID都是public的靜態變數,因此,可直接使用Field.get方法獲得這些變數的值。如果是private或protected的變數,需要field.setAccessible(true)設定變數值的訪問許可權才可以讀寫這些變數。
  2. 使用Field.get方法獲得變數值時,如果是靜態變數。Field.get方法的引數值設為null即可。如果不是靜態變數,需要為Field.get方法指定一個變數所在類的物件作為引數值。
  3. 由於EditText類不能直接插入Span物件,因此,需要先使用SpannableString物件來封裝Span物件(如本例中的ImageSpan物件),再將SpannableString物件插入到EditText控制元件中
  4. .html.length()此處一定要填入的html的長度,因為每個表情的名字長度是不一樣的,例如1-9的表情名字為ee_9,後面的名字為ee_10這樣的話,每次去擷取的長度是不一樣的,如果填入的是固定長度的話,比如4,前面9個沒事情,後面的點選就會卡死,因為它拿著4去擷取長度名字,佔不到自己要載入的資源名字,所以會造成ANR

通過

    // 利用反射機制,通過資源名字得到資源的ID
    public static int getResourceId(String resName) {
        try {
            Field field = R.drawable.class.getField(resName);
            return Integer.parseInt(field.get(null).toString());
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("TAG", "faild to get resource ID !");
        }
        return 0;
    }

通過這一步最後將我們要顯示的圖片顯示在textView上面

    /**
     * 通過圖片的名字,顯示圖片,主要用在TextView中
     * 
     * @param context
     * @param htmlString 圖片的名字
     * @return 可顯示的圖片的String型別
     */
    public static CharSequence formatString(final Context context,
            String htmlString) {
        CharSequence ch = Html.fromHtml(htmlString, new Html.ImageGetter() {

            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public Drawable getDrawable(String source) {
Drawable drawable = context.getResources().getDrawable(
getResourceId(source));
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
0drawable.getIntrinsicHeight());
                return drawable;
            }
        }, null);

        return ch;
    }

基本處理過程就是這樣,
小表情的佈局我們用gridview來實現
在gridview的Item點選事件監聽的時候,editText獲得輸入內容通過如下這句程式碼實現,記得要try-catch

et.append(ImageUtils.getSpanableString(MainActivity.this, EmoUtils.face_name[position]));

控制元件上面內容的顯示即textView內容的顯示
我們通過工具類中的formatString方法將表情顯示上去
此處傳入兩個引數
1.上下文 context
2.editText獲得到的內容et.getText().toString()

tv.setText(ImageUtils.formatString(MainActivity.this, et.getText().toString()));

最後就是我們adapter的書寫,程式碼如下

public class GridAdapter extends BaseAdapter {

    int[] face;
    Context context;

    public GridAdapter(Context context, int[] face) {
        // TODO Auto-generated constructor stub
        this.context = context;
        this.face = face;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return face.length;
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        View v = View.inflate(context, R.layout.item, null);
        ImageView im = (ImageView) v.findViewById(R.id.imageView1);
        im.setImageResource(face[position]);
        return v;
    }
}

小表情資源大家自己找下,找不到的話,直接下載QQ解壓出來,去一個res檔案下面找到
還有什麼不懂的,可以1215167396call我