android實現簡單聊天室

來源:互聯網
上載者:User

       最近寫了一個簡單的聊天室應用,可以發送表情,更改頭像這些功能。主要技術點就是怎樣把表情圖片放到textview等Ui控制項中展示。這裡廢話不多說,下面是:

 

這裡主要講下怎樣把文本替換到表情,先說下思路,首先我們的圖片是儲存在本地資來源目錄drawable中而所有的資源檔都是R這個類來管理,所以我們可以利用Regex找出圖片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); // 通過上面匹配得到的字串來產生圖片資源idif (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); // 將該圖片替換字串中規定的位置中if (end < spannableString.length()) { // 如果整個字串還未驗證完,則繼續。。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); // 通過傳入的Regex來產生一個patterntry {matchExpression(context, spannableString, sinaPatten, 0);} catch (Exception e) {Log.e("dealExpression", e.getMessage());}return spannableString;}}

下面是聊天記錄列表的adapter,這裡主要是動態改變每個Item的布局來區分是自己還是他人的發言,具體源碼如下:

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");}@Overridepublic int getCount() {return data.size();}@Overridepublic Object getItem(int position) {return data.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic 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())) {// 根據本地的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())); // 設定頭像} else {image.setImageResource(R.drawable.im);}String str = msg.getMessage(); // 訊息具體內容try {SpannableString spannableString = ExpressionUtil.getExpressionString(context, str, CommonUtils.PATTERN);text.setText(spannableString);} catch (Exception e) {e.printStackTrace();}}}}

 

好了,核心代碼已經上網,有興趣的可以下載源碼來研究!

源碼地址:http://download.csdn.net/detail/yaoyeyzq/4970408

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.