Android编写简单的聊天室应用

作者:楊先生 时间:2023-12-19 10:49:38 

最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能。主要技术点就是怎样把表情图片放到textview等Ui控件中展示。这里废话不多说,下面是效果图:

Android编写简单的聊天室应用

 这里主要讲下怎样把文本替换到表情,先说下思路,首先我们的图片是保存在本地资源目录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); // 将该图片替换字符串中规定的位置中
       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); // 通过传入的正则表达式来生成一个pattern
   try {
     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");
 }

@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())) {
       // 根据本地的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();
     }
   }
 }

}

源码下载:Android聊天室应用

标签:Android,聊天室
0
投稿

猜你喜欢

  • java中不定长参数的实例用法

    2021-06-17 02:49:35
  • Java C++ 算法题解leetcode145商品折扣后最终价格单调栈

    2023-09-16 23:29:42
  • Unity3d实现Flappy Bird游戏

    2023-09-17 20:54:29
  • Java实现简易计算器(逆波兰表达式)

    2022-06-17 13:48:23
  • Spring Boot 搭建 ELK正确看日志的配置流程

    2022-08-28 17:13:46
  • Java基础教程之static五大应用场景

    2023-11-11 05:10:43
  • C#调用WebService实例开发

    2022-11-21 22:51:08
  • Android切换至SurfaceView时闪屏(黑屏闪一下)以及黑屏移动问题的解决方法

    2023-07-21 10:51:45
  • JVM常量池的深入讲解

    2021-09-13 15:54:00
  • Java动态规划方式解决不同的二叉搜索树

    2023-03-02 01:56:52
  • Android将项目导出为Library并在项目中使用教程

    2022-01-31 14:57:17
  • java -jar设置添加启动参数实现方法

    2022-04-26 21:05:37
  • C#实现XML文件读取

    2023-03-06 13:38:44
  • Java如何实现Word文档分栏效果

    2023-09-11 00:28:53
  • Java抽象类和接口的区别详情

    2023-05-23 20:09:59
  • 一文带你学会Spring JDBC的使用

    2023-11-29 17:05:34
  • Kotlin 基础教程之类、对象、接口

    2022-03-12 04:22:15
  • Maven实战之搭建Maven私服和镜像的方法(图文)

    2023-11-27 22:27:06
  • Android常用的图片加载库

    2021-06-04 18:56:30
  • C#微信公众号开发之服务器配置

    2023-03-12 15:02:50
  • asp之家 软件编程 m.aspxhome.com