欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编写简单的聊天室应用

程序员文章站 2024-03-03 21:32:16
最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能。主要技术点就是怎样把表情图片放到textview等ui控件中展示。这里废话不多说,下面是效果图: &nb...

最近写了一个简单的聊天室应用,可以发送表情,更改头像这些功能。主要技术点就是怎样把表情图片放到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软件编程有所帮助,也希望大家多多支持。