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

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

首先我們需要知道Android 輸入的是EditText 顯示的內容是TextView, 但是TextView裏面又只能顯示字符串文字, 那怎麼能夠同時圖文展示呢? 接下來帶領你們展示是怎麼實現的。

既然需要展示表情,所有表情的圖片包還是需要大家去網上收集的在這裏就不和大家詳說了。當我們從網上下載圖片後如下圖這樣放在assets文件夾裏面,當前你也可以在裏面在建一個自己喜歡的目錄

在這裏插入圖片描述

然後我們需要全局首次加載這個圖片,使用集合存儲起來

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
































終於再我歷經一整天的努力下完成了,下面是我運行示例截圖,分享下, 這很簡單的, 網上很多。代碼就不分享了

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章