Android 最完整的仿QQ表情聊天图文展示代码示例

android 最完整的表情聊天特效(大家可以看我上一篇文章websocket的整合,这是他的后续)

首先我们需要知道Android 输入的是EditText 显示的内容是TextView, 但是TextView里面又只能显示字符串文字, 那怎么能够同时图文展示呢? 接下来带领你们展示是怎么实现的。

既然需要展示表情,所有表情的图片包还是需要大家去网上收集的在这里就不和大家详说了。当我们从网上下载图片后如下图这样放在assets文件夹里面,当前你也可以在里面在建一个自己喜欢的目录

Android 最完整的仿QQ表情聊天图文展示代码示例_第1张图片

然后我们需要全局首次加载这个图片,使用集合存储起来

public class ApplicationContext extends Application implements Thread.UncaughtExceptionHandler {
@Override
public void onCreate() {
super.onCreate();
x.Ext.init(this);
x.Ext.setDebug(false);
Thread.setDefaultUncaughtExceptionHandler(this);
initBiaoqingMap();
}
@Override
public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) {
System.exit(0);
}
public String getStringFromId(int stringId){
return getResources().getString(stringId);
}
private void initBiaoqingMap() {
biaoqingMap.put("[微笑]", “wechat_emotion_0.png”);
biaoqingMap.put("[撇嘴]", “wechat_emotion_1.png”);
biaoqingMap.put("[色]", “wechat_emotion_2.png”);
biaoqingMap.put("[发呆]", “wechat_emotion_3.png”);
biaoqingMap.put("[得意]", “wechat_emotion_4.png”);
biaoqingMap.put("[流泪]", “wechat_emotion_5.png”);
biaoqingMap.put("[害羞]", “wechat_emotion_6.png”);
biaoqingMap.put("[闭嘴]", “wechat_emotion_7.png”);
biaoqingMap.put("[睡]", “wechat_emotion_8.png”);
biaoqingMap.put("[大哭]", “wechat_emotion_9.png”);
biaoqingMap.put("[尴尬]", “wechat_emotion_10.png”);
biaoqingMap.put("[发怒]", “wechat_emotion_11.png”);
biaoqingMap.put("[调皮]", “wechat_emotion_12.png”);
biaoqingMap.put("[呲牙]", “wechat_emotion_13.png”);
biaoqingMap.put("[惊讶]", “wechat_emotion_14.png”);
biaoqingMap.put("[难过]", “wechat_emotion_15.png”);
}
}

然后再聊天界面首次用到的时候加载

@ViewInject(R.id.chat_biaoqing_GridView)
private GridView chat_biaoqing_GridView;
private BiaoqingAdapter biaoqingAdapter;
private String[] wechatemojis;
private void initBaioqing(){
try {
wechatemojis = getResources().getAssets().list(Common.biaoqing_path);
biaoqingAdapter = new BiaoqingAdapter(wechatemojis, getBaseActivityContext());
chat_biaoqing_GridView.setAdapter(biaoqingAdapter);
chat_biaoqing_GridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
String fileName = wechatemojis[position];
String mapKey = getBiaoqingkeyFromValue(fileName);
chat_input.append(mapKey);
}
});
} catch (IOException e) {
e.printStackTrace();
}
}

这样有啥用呢, 这样我们就可以用文字和图片关联起来, 并且还能再Textview中显示了,通过自定义控件特殊字符串转图片的形式实现图文展示,控件代码如下:

@SuppressLint(“AppCompatCustomView”)
public class BiaoQingTextView extends TextView {
public BiaoQingTextView(Context context) {
super(context);
}
public BiaoQingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BiaoQingTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void initView(Context context){
String str = getText().toString();
if(str==null||"".equals(str)) {
this.setText("");
return;
}
try{
InputStream bitmap=null;
SpannableString ss = new SpannableString(str);
Bitmap bit=null;
//处理显示表情
String content = str;
int len = 0;
int starts = 0;
int end = 0;
while(len < content.length()){
if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){
starts = content.indexOf("[", starts);
end = content.indexOf("]", end);
String phrase = content.substring(starts,end + 1);
String value = biaoqingMap.get(phrase);
try {
bitmap = context.getResources().getAssets().open(biaoqing_path + “/” + value);
bit= BitmapFactory.decodeStream(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
Drawable drawable = new BitmapDrawable(bit);
try {
if (drawable != null) {
drawable.setBounds(0, 0, 65, 65);
VerticalImageSpan span = new VerticalImageSpan(drawable);
ss.setSpan(span, starts,end + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
} catch (SecurityException e) {
e.printStackTrace();
}
starts = end;
len = end;
end++;
}else{
starts++;
end++;
len = end;
}
}
this.setText(ss);
} catch (Exception e) {
e.printStackTrace();
}
}
}

使用这个控件的时候需要set数据后再initView()一下,然后本地上就差不多了, 但是我调试出现一下很大的bug, 就是文字和图片没对齐, 原因可能是图片的大小的文字不匹配这时我们就应该这样操作把文字和图片横向对齐

public class VerticalImageSpan extends ImageSpan {
public VerticalImageSpan(Drawable drawable) {
super(drawable);
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end,
Paint.FontMetricsInt fontMetricsInt) {
Drawable drawable = getDrawable();
Rect rect = drawable.getBounds();
if (fontMetricsInt != null) {
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.bottom - fmPaint.top;
int drHeight = rect.bottom - rect.top;
int top = drHeight / 2 - fontHeight / 4;
int bottom = drHeight / 2 + fontHeight / 4;
fontMetricsInt.ascent = -bottom;
fontMetricsInt.top = -bottom;
fontMetricsInt.bottom = top;
fontMetricsInt.descent = top;
}
return rect.right;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end,
float x, int top, int y, int bottom, Paint paint) {
Drawable drawable = getDrawable();
canvas.save();
int transY = 0;
transY = ((bottom - top) - drawable.getBounds().bottom) / 2 + top;
canvas.translate(x, transY);
drawable.draw(canvas);
canvas.restore();
}
}

终于再我历经一整天的努力下完成了,下面是我运行示例截图,分享下, 这很简单的, 网上很多。代码就不分享了

Android 最完整的仿QQ表情聊天图文展示代码示例_第2张图片
Android 最完整的仿QQ表情聊天图文展示代码示例_第3张图片
Android 最完整的仿QQ表情聊天图文展示代码示例_第4张图片

你可能感兴趣的:(编程)