android在EditText中插入表情圖片

jopen 12年前發布 | 62K 次閱讀 Android Android開發 移動開發

EditText通常用于顯示文字,但有時候也需要在文字中夾雜一些圖片,比如QQ中就可以使用表情圖片,又比如需要的文字高亮顯示等等,如何在android中也做到這樣呢? 
記得android中有個android.text包,這里提供了對文本的強大的處理功能。 

添加圖片主要用SpannableStringImageSpan類,具體參考sdk文檔 SpannableString

 

這里以人人網客戶端發布消息的界面為例

 

布局文件main.xml

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:background="#FFFFFF"  
        android:orientation="vertical" >  

        <LinearLayout  
            android:layout_width="fill_parent"  
            android:layout_height="48dip"  
            android:background="@drawable/v5_0_1_flipper_head_blue_background"  
            android:orientation="horizontal" >  

            <ImageView  
                android:id="@+id/newsfeedpublish_back"  
                android:layout_width="54dip"  
                android:layout_height="fill_parent"  
                android:layout_gravity="center"  
                android:background="@drawable/v5_0_1_flipper_head_title_wrapper_background"  
                android:clickable="true"  
                android:scaleType="centerInside"  
                android:src="@drawable/v5_0_1_flipper_head_back" />  

            <ImageView  
                android:layout_width="2px"  
                android:layout_height="24dip"  
                android:layout_gravity="center"  
                android:src="@drawable/v5_0_1_flipper_head_separator" />  

            <TextView  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:gravity="center_vertical"  
                android:paddingLeft="8dip"  
                android:text="發布新鮮事"  
                android:textColor="#FFFFFF"  
                android:textSize="16sp"  
                android:textStyle="bold" />  

            <ImageView  
                android:id="@+id/newsfeedpublish_publish"  
                android:layout_width="54dip"  
                android:layout_height="fill_parent"  
                android:background="@drawable/v5_0_1_flipper_head_title_wrapper_background"  
                android:clickable="true"  
                android:scaleType="centerInside"  
                android:src="@drawable/v5_0_1_flipper_head_publish" />  
        </LinearLayout>  

        <EditText  
            android:id="@+id/newsfeedpublish_content"  
            android:layout_width="fill_parent"  
            android:layout_height="wrap_content"  
            android:layout_marginBottom="8dip"  
            android:layout_weight="1"  
            android:background="#00000000"  
            android:gravity="top"  
            android:hint="您正在干嘛?"  
            android:maxLength="140"  
            android:padding="8dip"  
            android:textColor="#000000"  
            android:textSize="16sp" >  

            <requestFocus />  
        </EditText>  

        <View  
            android:layout_width="fill_parent"  
            android:layout_height="1dip"  
            android:layout_marginLeft="8dip"  
            android:layout_marginRight="8dip"  
            android:background="@drawable/v5_0_1_publisher_split_line" />  

        <LinearLayout  
            android:layout_width="fill_parent"  
            android:layout_height="40dip"  
            android:orientation="horizontal" >  

            <LinearLayout  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_margin="5dip"  
                android:layout_weight="1"  
                android:background="@drawable/v5_0_1_publisher_poi_text_bg"  
                android:orientation="horizontal" >  

                <Button  
                    android:id="@+id/newsfeedpublish_poi_place"  
                    android:layout_width="wrap_content"  
                    android:layout_height="fill_parent"  
                    android:layout_weight="1"  
                    android:background="#00000000"  
                    android:drawableLeft="@drawable/v5_0_1_publisher_poi_icon"  
                    android:drawablePadding="8dip"  
                    android:ellipsize="start"  
                    android:gravity="left|center_vertical"  
                    android:singleLine="true"  
                    android:text="正在定位..."  
                    android:textColor="#ff005092" />  

                <ImageView  
                    android:id="@+id/newsfeedpublish_poi_sperator"  
                    android:layout_width="1dip"  
                    android:layout_height="fill_parent"  
                    android:src="@drawable/v5_0_1_publisher_poi_area_sperator" />  

                <ImageView  
                    android:id="@+id/newsfeedpublish_poi_list"  
                    android:layout_width="wrap_content"  
                    android:layout_height="wrap_content"  
                    android:layout_gravity="center_vertical"  
                    android:src="@drawable/v5_0_1_publisher_poi_list_icon"  
                    android:visibility="invisible" />  
            </LinearLayout>  

            <LinearLayout  
                android:layout_width="100dip"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:gravity="right"  
                android:padding="8dip" >  

                <TextView  
                    android:id="@+id/newsfeedpublish_count"  
                    android:layout_width="wrap_content"  
                    android:layout_height="fill_parent"  
                    android:gravity="center"  
                    android:text="0"  
                    android:textColor="#80333333"  
                    android:textSize="14sp" />  

                <TextView  
                    android:layout_width="wrap_content"  
                    android:layout_height="fill_parent"  
                    android:gravity="center"  
                    android:text="/140"  
                    android:textColor="#80333333"  
                    android:textSize="14sp" />  
            </LinearLayout>  
        </LinearLayout>  

        <LinearLayout  
            android:layout_width="fill_parent"  
            android:layout_height="40dip"  
            android:background="@drawable/v5_0_1_publisher_buttons_area_bg"  
            android:orientation="horizontal" >  

            <ImageButton  
                android:id="@+id/newsfeedpublish_voice"  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:background="@drawable/v5_0_1_publisher_button_bg"  
                android:src="@drawable/v5_0_1_publisher_voice_button" />  

            <ImageButton  
                android:id="@+id/newsfeedpublish_poi"  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:background="@drawable/v5_0_1_publisher_button_bg"  
                android:src="@drawable/v5_0_1_publisher_poi_button_on" />  

            <ImageButton  
                android:id="@+id/newsfeedpublish_image"  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:background="@drawable/v5_0_1_publisher_button_bg"  
                android:src="@drawable/v5_0_1_publisher_image_button" />  

            <ImageButton  
                android:id="@+id/newsfeedpublish_at"  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:background="@drawable/v5_0_1_publisher_button_bg"  
                android:src="@drawable/v5_0_1_publisher_at_button" />  

            <ImageButton  
                android:id="@+id/newsfeedpublish_emoticon"  
                android:layout_width="wrap_content"  
                android:layout_height="fill_parent"  
                android:layout_weight="1"  
                android:background="@drawable/v5_0_1_publisher_button_bg"  
                android:src="@drawable/v5_0_1_publisher_emotion_button" />  
        </LinearLayout>  

        <GridView  
            android:id="@+id/newsfeedpublish_emoticons"  
            android:layout_width="fill_parent"  
            android:layout_height="200dip"  
            android:background="@drawable/v5_0_1_publisher_emotion_area_bg"  
            android:cacheColorHint="#00000000"  
            android:focusableInTouchMode="true"  
            android:horizontalSpacing="5dip"  
            android:listSelector="#00000000"  
            android:numColumns="8"  
            android:stretchMode="columnWidth"  
            android:verticalSpacing="5dip"  
            android:visibility="gone" >  
        </GridView>  

    </LinearLayout>  

MainActivity.java

    package com.yulore.emotion;  

    import android.app.Activity;  
    import android.os.Bundle;  
    import android.util.Log;  
    import android.view.View;  
    import android.view.View.OnClickListener;  
    import android.view.ViewGroup;  
    import android.view.inputmethod.InputMethodManager;  
    import android.widget.AdapterView;  
    import android.widget.AdapterView.OnItemClickListener;  
    import android.widget.BaseAdapter;  
    import android.widget.EditText;  
    import android.widget.GridView;  
    import android.widget.ImageButton;  
    import android.widget.ImageView;  

    public class MainActivity extends Activity implements OnClickListener {  
        private static final String TAG = "MainActivity";  
        private ImageButton ib_emotion;  
        private GridView gv_emotion;  
        private EmotionAdapter mAdapter;  
        private EditText et_content;  
        private ImageView iv_publish;  

        /** Called when the activity is first created. */  
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  

            findViewById();  
            initEmotionIcons();  
            setListener();  

            mAdapter = new EmotionAdapter();  
            gv_emotion.setAdapter(mAdapter);  
        }  

        private void initEmotionIcons() {  
            String json = EmotionUtil.getInstance().readFromFile(EmotionUtil.DOWNLOAD_EMOTION_PATH, "Emoticons.json");  
            if(json!=null){  
                Log.e(TAG, json);  
                RenRenData.mEmotionList = new DataProvider().resolve(json);  
            }  
        }  

        private void findViewById() {  
            ib_emotion = (ImageButton) findViewById(R.id.newsfeedpublish_emoticon);  
            gv_emotion = (GridView) findViewById(R.id.newsfeedpublish_emoticons);  
            et_content = (EditText) findViewById(R.id.newsfeedpublish_content);  
            iv_publish = (ImageView) findViewById(R.id.newsfeedpublish_publish);  
        }  

        private void setListener() {  
            ib_emotion.setOnClickListener(this);  
            et_content.setOnClickListener(this);  

            gv_emotion.setOnItemClickListener(new OnItemClickListener() {  

                @Override  
                public void onItemClick(AdapterView<?> parent, View view,  
                        int position, long id) {  

                    String emotion = RenRenData.mEmotionList.get(position).getEmotion();  

                    if(et_content.getText().length()+emotion.length()<=140){ //長度小于140  

    //                  et_content.setText(et_content.getText().toString()+emotion);  
                        CharSequence ret = EmotionUtil.getInstance().replace(getApplicationContext(), et_content.getText().toString()+emotion);  
                        Log.e(TAG, "ret="+ret);  
                        et_content.setText(ret);  
                    }  
                }  
            });  
        }  

        @Override  
        public void onClick(View v) {  
            switch (v.getId()) {  
            case R.id.newsfeedpublish_emoticon:  
                if(gv_emotion.isShown()){  
                    gv_emotion.setVisibility(View.GONE);  
                    ib_emotion.setImageResource(R.drawable.v5_0_1_publisher_emotion_button);  
                }else{  
                    gv_emotion.setVisibility(View.VISIBLE);  
                    ib_emotion.setImageResource(R.drawable.v5_0_1_publisher_pad_button);  

                    //隱藏輸入法界面  
                    InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);  
                    imm.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);  
                }  
                break;  
            case R.id.newsfeedpublish_content:  
                if(gv_emotion.isShown()){  
                    gv_emotion.setVisibility(View.GONE);  
                    ib_emotion.setImageResource(R.drawable.v5_0_1_publisher_emotion_button);  
                }  
                break;  

            default:  
                break;  
            }  
        }  

        private class EmotionAdapter extends BaseAdapter{  

            @Override  
            public int getCount() {  

                return RenRenData.mEmotionList.size();  
            }  

            @Override  
            public Object getItem(int position) {  

                return RenRenData.mEmotionList.get(position);  
            }  

            @Override  
            public long getItemId(int position) {  

                return position;  
            }  

            @Override  
            public View getView(int position, View convertView, ViewGroup parent) {  
                View view;  
                ViewHolder holder;  
                if(convertView==null){  
                    holder = new ViewHolder();  
                    view = View.inflate(getApplicationContext(), R.layout.emotion_item, null);  
                    holder.iv_emotion = (ImageView) view.findViewById(R.id.emotcons_item_img);  

                    view.setTag(holder);  
                }else{  
                    view = convertView;  
                    holder = (ViewHolder) view.getTag();  
                }  
                EmotionIcon em = RenRenData.mEmotionList.get(position);  
                holder.iv_emotion.setImageBitmap(EmotionUtil.getInstance().getLocalEmotionIcon(em.getEmotion()));  

                return view;  
            }  
        }  

        public static class ViewHolder{  
            public ImageView iv_emotion;  
        }  
    }  


EmotionUtil.java

package com.yulore.emotion;  

import java.io.BufferedInputStream;  
import java.io.BufferedReader;  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.InputStreamReader;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  

import android.content.Context;  
import android.graphics.Bitmap;  
import android.graphics.BitmapFactory;  
import android.os.Environment;  
import android.text.Spannable;  
import android.text.SpannableStringBuilder;  
import android.text.style.ImageSpan;  

public class EmotionUtil {  

    public static final String DOWNLOAD_EMOTION_PATH = Environment  
            .getExternalStorageDirectory().getAbsolutePath()  
            + "/RenRenForAndroid/Emoticons/";  

    private static EmotionUtil instance = new EmotionUtil();  

    private EmotionUtil() {  
    };  

    public static EmotionUtil getInstance() {  

        return instance;  
    }  

    /** 
     * 將文本中的表情符號替換為表情圖片 
     *  
     * @param text 
     *            需要轉換的字符 
     * @return 帶有表情的字符 
     */  
    public CharSequence replace(Context context,CharSequence text) {  
        try {  
            SpannableStringBuilder builder = new SpannableStringBuilder(text);  
            Pattern pattern = buildPattern();  
            Matcher matcher = pattern.matcher(text);  
            while (matcher.find()) {  
                Bitmap bitmap = getLocalEmotionIcon(matcher.group());  
                ImageSpan span = new ImageSpan(context, bitmap);  
                builder.setSpan(span, matcher.start(), matcher.end(),  
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
            }  
            return builder;  
        } catch (Exception e) {  
            return text;  
        }  
    }  

    /** 
     * 正則表達式 
     *  
     * @return 
     */  
    private Pattern buildPattern() {  
        /** 
         * 查看表情名稱數據是否存在,不存在則從本地讀取Json,并解析 
         */  
        if(RenRenData.mEmotionList==null || RenRenData.mEmotionList.size()==0){  

            String json = EmotionUtil.getInstance().readFromFile(EmotionUtil.DOWNLOAD_EMOTION_PATH, "Emoticons.json");  

            if(json!=null){  
                RenRenData.mEmotionList = new DataProvider().resolve(json);  
            }  
        }  

        StringBuilder patternString = new StringBuilder(  
                RenRenData.mEmotionList.size() * 3);  
        patternString.append('(');  
        for (EmotionIcon result : RenRenData.mEmotionList) {  
            String s = result.getEmotion();  
            patternString.append(Pattern.quote(s));  
            patternString.append('|');  
        }  
        patternString.replace(patternString.length() - 1,  
                patternString.length(), ")");  
        return Pattern.compile(patternString.toString());  
    }  

    public String readFromFile(String filePath, String fileName) {  
        if (fileName == null || "".equals(fileName)) {  
            return null;  
        }  
        String ret = "";  
        if (Environment.MEDIA_MOUNTED.equals(Environment  
                .getExternalStorageState())) {  

            File dir = new File(filePath);  
            if (dir == null || !dir.exists()) {  
                dir.mkdirs();  
            }  

            File targetFile = new File(filePath + fileName);  
            try {  

                if (targetFile == null || targetFile.exists()) {  
                    targetFile.createNewFile();  
                }  

                InputStream in = new BufferedInputStream(new FileInputStream(  
                        targetFile));  
                BufferedReader br = new BufferedReader(new InputStreamReader(  
                        in, "UTF-8"));  
                String tmp;  
                while ((tmp = br.readLine()) != null) {  
                    ret += tmp;  
                }  
                br.close();  
                in.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  

        return ret;  
    }  

    /** 
     * 根據表情名稱查找表情圖片 
     * @param imageName 
     * @return 
     */  
    public Bitmap getEmotionIcon(String imageName) {  

        File cacheDir = new File(DOWNLOAD_EMOTION_PATH);  

        if (!cacheDir.exists()) {  
            cacheDir.mkdirs();  
        }  

        File[] cacheFiles = cacheDir.listFiles();  
        int i = 0;  
        if (cacheFiles != null) {  
            for (; i < cacheFiles.length; i++) {  
                if (imageName.equals(cacheFiles[i].getName())) {  
                    break;  
                }  
            }  
        }  
        if (i < cacheFiles.length) {  
            return BitmapFactory.decodeFile(DOWNLOAD_EMOTION_PATH + imageName);  
        }  
        return null;  
    }  

    /** 
     * 從SD卡中根據表情符號獲取表情圖片 
     *  
     * @param imageName 
     *            表情的名稱 
     * @return 表情的Bitmap 
     */  
    public Bitmap getLocalEmotionIcon(String imageName) {  

        File dir = new File(DOWNLOAD_EMOTION_PATH);  
        if (!dir.exists()) {  
            dir.mkdirs();  
        }  

        File[] cacheFiles = dir.listFiles();  

        int index = 0;  

        for (int i = 0; cacheFiles != null && i < cacheFiles.length; i++) {  

            if (imageName.equals(cacheFiles[i].getName())) {  
                index = i;  
                break;  
            }  
        }  

        Bitmap bitmap = null;  

        if (index < cacheFiles.length) {  
            /** 
             * 因表情圖片較小,則這里返回了一個60*60的Bitmap,該數值可根據情況調整 
             */  
            bitmap = Bitmap  
                    .createScaledBitmap(  
                            BitmapFactory.decodeFile(DOWNLOAD_EMOTION_PATH  
                                    + imageName), 60, 60, true);  
        }  

        return bitmap;  
    }  

    /** 
     * 將文本中的表情符號轉換為表情圖片 
     *  
     * @param text 
     * @return 
     */  
    /*public CharSequence replace02(Context context, CharSequence text, int resId) { 
        // SpannableString連續的字符串,長度不可變,同時可以附加一些object;可變的話使用SpannableStringBuilder,參考sdk文檔 
        SpannableString ss = new SpannableString(text.toString() + "[smile]"); 
        // 得到要顯示圖片的資源 
        Drawable d = context.getResources().getDrawable(resId); 
        // 設置高度 
        d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); 
        // 跨度底部應與周圍文本的基線對齊 
        ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE); 
        // 附加圖片 
        ss.setSpan(span, text.length(), text.length() + "[smile]".length(), 
                Spannable.SPAN_INCLUSIVE_EXCLUSIVE); 

        return ss; 
    }*/  
}  
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!