android在EditText中插入表情圖片
EditText通常用于顯示文字,但有時候也需要在文字中夾雜一些圖片,比如QQ中就可以使用表情圖片,又比如需要的文字高亮顯示等等,如何在android中也做到這樣呢?
記得android中有個android.text包,這里提供了對文本的強大的處理功能。
添加圖片主要用SpannableString和ImageSpan類,具體參考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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!