Android編寫簡單的聊天室應(yīng)用
最近寫了一個簡單的聊天室應(yīng)用,可以發(fā)送表情,更改頭像這些功能。主要技術(shù)點就是怎樣把表情圖片放到textview等Ui控件中展示。這里廢話不多說,下面是效果圖:
這里主要講下怎樣把文本替換到表情,先說下思路,首先我們的圖片是保存在本地資源目錄drawable中而所有的資源文件都是R這個類來管理,所以我們可以利用正則表達式找出圖片id包裝成ImageSpan然后把ImageSpan放到SpannableString中,最后把SpannableString放入edittext中,下面是源碼:
package com.coreandroid.util; import java.lang.reflect.Field; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.content.Context; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ImageSpan; import android.util.Log; import com.coreandroid.chart.R; public class ExpressionUtil { /** * 對spanableString進行正則判斷,如果符合要求,則以表情圖片代替 * * @param context * @param spannableString * @param patten * @param start */ public static void matchExpression(Context context, SpannableString spannableString, Pattern patten, int start) throws Exception { Matcher matcher = patten.matcher(spannableString); while (matcher.find()) { String key = matcher.group(); if (matcher.start() < start) { continue; } Field field = R.drawable.class.getDeclaredField(key); int resId = field.getInt(null); // 通過上面匹配得到的字符串來生成圖片資源id if (resId != 0) { ImageSpan imageSpan = new ImageSpan(context, resId); // 通過圖片資源id來得到bitmap,用一個ImageSpan來包裝 int end = matcher.start() + key.length(); // 計算該圖片名字的長度,也就是要替換的字符串的長度 spannableString.setSpan(imageSpan, matcher.start(), end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // 將該圖片替換字符串中規(guī)定的位置中 if (end < spannableString.length()) { // 如果整個字符串還未驗證完,則繼續(xù)。。 matchExpression(context, spannableString, patten, end); } break; } } } /** * 得到一個SpanableString對象,通過傳入的字符串,并進行正則判斷 * * @param context * @param str * @return SpannableString */ public static SpannableString getExpressionString(Context context, String str, String zhengze) { SpannableString spannableString = new SpannableString(str); Pattern sinaPatten = Pattern.compile(zhengze); // 通過傳入的正則表達式來生成一個pattern try { matchExpression(context, spannableString, sinaPatten, 0); } catch (Exception e) { Log.e("dealExpression", e.getMessage()); } return spannableString; } }
下面是聊天記錄列表的adapter,這里主要是動態(tài)的改變每個Item的布局來區(qū)分是自己還是他人的發(fā)言,具體源碼如下:
package com.coreandroid.adapter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import android.content.Context; import android.text.SpannableString; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.coreandroid.chart.R; import com.coreandroid.entity.MessageInfo; import com.coreandroid.util.CommonUtils; import com.coreandroid.util.ExpressionUtil; public class ChartListAdapter extends BaseAdapter { private Context context; private LayoutInflater inflater; private List<MessageInfo> data; private DateFormat df; public ChartListAdapter(Context context, List<MessageInfo> data) { super(); this.context = context; inflater = LayoutInflater.from(context); this.data = data; df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { convertView = inflater.inflate(R.layout.chart_list_item, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.setData((MessageInfo) getItem(position)); return convertView; } private class ViewHolder { private ImageView image; private TextView text; private TextView title; private RelativeLayout rl; public ViewHolder(View convertView) { image = (ImageView) convertView .findViewById(R.id.chart_list_item_headicon); text = (TextView) convertView .findViewById(R.id.chart_list_item_message); title = (TextView) convertView .findViewById(R.id.chart_list_item_title); rl = (RelativeLayout) convertView .findViewById(R.id.rl_chart_list_bottom); } public void setData(MessageInfo msg) { RelativeLayout.LayoutParams rl_tv_msg_left = (RelativeLayout.LayoutParams) text .getLayoutParams(); RelativeLayout.LayoutParams rl_iv_headicon_left = (RelativeLayout.LayoutParams) image .getLayoutParams(); RelativeLayout.LayoutParams rl_tv_title = (RelativeLayout.LayoutParams) title .getLayoutParams(); RelativeLayout.LayoutParams rl_buttom = (RelativeLayout.LayoutParams) rl .getLayoutParams(); if (!CommonUtils.getDeviceId().equalsIgnoreCase(msg.getUsermac())) { // 根據(jù)本地的mac地址來判斷該條信息是屬于本人所說還是對方所說 // 如果是自己說的,則顯示在右邊;如果是對方所說,則顯示在左邊 rl_buttom.addRule(RelativeLayout.ALIGN_PARENT_TOP); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_LEFT); rl_tv_title.addRule(RelativeLayout.BELOW, R.id.rl_chart_list_bottom); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_LEFT); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_msg_left.addRule(RelativeLayout.RIGHT_OF, R.id.chart_list_item_headicon); text.setBackgroundResource(R.drawable.incoming); String titleStr = msg.getUsermac() + "-" + df.format(new Date()); title.setText(titleStr); } else { rl_buttom.addRule(RelativeLayout.ALIGN_PARENT_TOP); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_title.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rl_tv_title.addRule(RelativeLayout.BELOW, R.id.rl_chart_list_bottom); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); rl_iv_headicon_left.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); rl_tv_msg_left.addRule(RelativeLayout.LEFT_OF, R.id.chart_list_item_headicon); text.setBackgroundResource(R.drawable.outgoing); String titleStr = df.format(new Date()) + "-" + msg.getUsermac(); title.setText(titleStr); } if (!TextUtils.isEmpty(msg.getHeadImage())) { image.setImageBitmap(CommonUtils.strConvertBitmap(msg .getHeadImage())); // 設(shè)置頭像 } else { image.setImageResource(R.drawable.im); } String str = msg.getMessage(); // 消息具體內(nèi)容 try { SpannableString spannableString = ExpressionUtil .getExpressionString(context, str, CommonUtils.PATTERN); text.setText(spannableString); } catch (Exception e) { e.printStackTrace(); } } } }
源碼下載:Android聊天室應(yīng)用
以上就是本文的全部內(nèi)容,希望對大家學(xué)習Android軟件編程有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android實現(xiàn)Activity、Service與Broadcaster三大組件之間互相調(diào)用的方法詳解
這篇文章主要介紹了Android實現(xiàn)Activity、Service與Broadcaster三大組件之間互相調(diào)用的方法,結(jié)合實例形式詳細分析了Activity、Service與Broadcaster三大組件相互調(diào)用的原理,實現(xiàn)方法與相關(guān)注意事項,需要的朋友可以參考下2016-03-03Android實現(xiàn)動態(tài)高斯模糊效果示例代碼
這篇文章主要介紹了Android快速實現(xiàn)動態(tài)模糊效果示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-01-01Android設(shè)備藍牙連接掃描槍獲取掃描內(nèi)容
這篇文章主要為大家詳細介紹了Android設(shè)備藍牙連接掃描槍獲取掃描內(nèi)容,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09