首先看一下最终的效果,显示了消息时间,用户昵称,用户头像。

大致实现方法:

  用最简单的ListView显示消息内容。

  不同的用户使用不同的消息布局文件,从而达到头像左右显示的效果,如上图有2个用户"Tony","Hill",头像分别显示在左右两边。

代码文件清单:

  主布局文件activity_main.xml:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
tools:context=".MainActivity" >
<ListView
android:id="@+id/lv_message"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:layout_above="@+id/ll_send_1"
android:scrollbars="none"
android:divider="@null"
android:footerDividersEnabled="false">
</ListView>
<LinearLayout
android:id="@+id/ll_send_1"
android:layout_height="50dp"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_above="@+id/ll_send_2">
<EditText
android:id="@+id/et_tony_message"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="3"
android:hint="Tony请输入"/>
<Button
android:id="@+id/but_tony_send"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:text="send"/>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_send_2"
android:layout_height="50dp"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_alignParentBottom="true">
<EditText
android:id="@+id/et_hill_message"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="3"
android:hint="Hill请输入"/>
<Button
android:id="@+id/but_hill_send"
android:layout_height="fill_parent"
android:layout_width="0dp"
android:layout_weight="1"
android:text="send"/>
</LinearLayout>
</RelativeLayout>

  头像位于左边的消息布局文件list_message_item_left.xml:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/chat_list_item_background"
android:padding="6dp"> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"> <TextView
android:id="@+id/tv_sendtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#8B8B8B"
android:textSize="12sp"
android:text="15:03:15"/>
</LinearLayout> <RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"> <ImageView
android:id="@+id/iv_userhead"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/head_portrait_1"
android:focusable="false"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" /> <TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginBottom="5dp"
android:textColor="#8B8B8B"
android:layout_toRightOf="@id/iv_userhead"
android:text="name"/> <TextView
android:id="@+id/tv_chatcontent"
android:layout_toRightOf="@id/iv_userhead"
android:layout_marginLeft="10dp"
android:layout_marginRight="40dp"
android:layout_below="@id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:background="@drawable/message_text_background01"/>
</RelativeLayout>
</LinearLayout>

  头像位于右边的消息布局文件list_message_item_right.xml:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/chat_list_item_background"
android:padding="6dp"> <LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal"> <TextView
android:id="@+id/tv_sendtime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#8B8B8B"
android:textSize="12sp"
android:text="15:03:15"/>
</LinearLayout>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" > <ImageView
android:id="@+id/iv_userhead"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="@drawable/head_portrait_2"
android:focusable="false"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" /> <TextView
android:id="@+id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_marginBottom="5dp"
android:textColor="#8B8B8B"
android:layout_toLeftOf="@id/iv_userhead"
android:text="name"/> <TextView
android:id="@+id/tv_chatcontent"
android:layout_toLeftOf="@id/iv_userhead"
android:layout_marginRight="10dp"
android:layout_marginLeft="40dp"
android:layout_below="@id/tv_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
android:background="@drawable/message_text_background02"/>
</RelativeLayout> </LinearLayout>

  主界面java代码文件MainActivity.java:

 public class MainActivity extends Activity implements OnClickListener{
EditText et_tony_message;
Button but_tony_send; EditText et_hill_message;
Button but_hill_send; ListView lv_message;
List<Message> list;
MessageAdapter adapter;
Handler handler=new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
} private void init() {
et_tony_message=(EditText) findViewById(R.id.et_tony_message);
but_tony_send=(Button) findViewById(R.id.but_tony_send);
but_tony_send.setOnClickListener(this); et_hill_message=(EditText) findViewById(R.id.et_hill_message);
but_hill_send=(Button) findViewById(R.id.but_hill_send);
but_hill_send.setOnClickListener(this); list=new ArrayList<Message>();
lv_message=(ListView) findViewById(R.id.lv_message);
adapter=new MessageAdapter();
lv_message.setAdapter(adapter);
} @Override
public void onClick(View v) {
/*Tony发送消息*/
if(v==but_tony_send){
/*验证*/
if(et_tony_message.getText()==null||et_tony_message.getText().toString().equals("")){
Toast.makeText(this, "消息不能为空", 0).show();
return ;
}
Message m=new Message();
m.setFrom_username("Tony");
m.setCreate_time(System.currentTimeMillis());
m.setText(et_tony_message.getText().toString());
sendMessage(m);
et_tony_message.setText("");
}
/*Hill发送消息*/
if(v==but_hill_send){
/*验证*/
if(et_hill_message.getText()==null||et_hill_message.getText().toString().equals("")){
Toast.makeText(this, "消息不能为空", 0).show();
return ;
}
Message m=new Message();
m.setFrom_username("Hill");
m.setCreate_time(System.currentTimeMillis());
m.setText(et_hill_message.getText().toString());
sendMessage(m);
et_hill_message.setText("");
}
}
private void sendMessage(Message m) {
list.add(m);
adapter.notifyDataSetChanged();
// lv_message.f
lv_message.setSelection(list.size()+1);
}
class MessageAdapter extends BaseAdapter{ @Override
public int getCount() {
return list.size();
} @Override
public Object getItem(int position) {
return list.get(position);
} @Override
public long getItemId(int position) {
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
Message message=list.get(position);
ViewHolder viewHolder=null;
// if(convertView==null){
if("Tony".equalsIgnoreCase(message.getFrom_username())){
convertView=parent.inflate(MainActivity.this, R.layout.list_message_item_left, null);
}else{
convertView=parent.inflate(MainActivity.this, R.layout.list_message_item_right, null);
}
viewHolder=new ViewHolder();
viewHolder.iv_userhead=(ImageView) convertView.findViewById(R.id.iv_userhead);
viewHolder.tv_chatcontent=(TextView) convertView.findViewById(R.id.tv_chatcontent);
viewHolder.tv_sendtime=(TextView) convertView.findViewById(R.id.tv_sendtime);
viewHolder.tv_username=(TextView) convertView.findViewById(R.id.tv_username);
// convertView.setTag(viewHolder);
// }else{
// viewHolder=(ViewHolder) convertView.getTag();
// } viewHolder.tv_chatcontent.setText(message.getText());
viewHolder.tv_sendtime.setText(new SimpleDateFormat("HH:mm:ss").format(new Date(message.getCreate_time())));
viewHolder.tv_username.setText(message.getFrom_username());
return convertView;
}
class ViewHolder{
public ImageView iv_userhead;
public TextView tv_username;
public TextView tv_chatcontent;
public TextView tv_sendtime;
}
}
}

  消息封装代码文件Message.java:

 public class Message {
private String from_username;/*发送者*/
private Long create_time;/*发送时间*/
private String text;/*消息内容*/
public String getFrom_username() {
return from_username;
} public Long getCreate_time() {
return create_time;
}
public void setCreate_time(Long create_time) {
this.create_time = create_time;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
} public void setFrom_username(String from_username) {
this.from_username = from_username;
} }

源码下载:http://www.apkbus.com/forum.php?mod=viewthread&tid=173419&extra=

简单模仿QQ聊天界面的更多相关文章

  1. QQ聊天界面的布局和设计(IOS篇)-第二季

    QQChat Layout - 第二季 本来第二季是快写好了, 也花了点功夫, 结果gitbook出了点问题, 给没掉了.有些细节可能会一带而过, 如有疑问, 相互交流进步~. 在第一季中我们完成了Q ...

  2. Qt 之 模仿 QQ登陆界面——样式篇

    一.简述 今天晚上花了半天时间从QQ登录界面抠了些图,顺便加了点样式基本上实现了QQ的登陆界面全部效果.虽不说100%相似,那也有99.99%相似了哈O(∩_∩)O. QQ好像从去年开始,登录界面有了 ...

  3. Objective-c——UI基础开发第八天(QQ聊天界面)

    一.知识点: QQ聊天界面 双模型的使用(dataModel和frameModel) UITextField的使用 通知的使用 拉伸图片的两种方法(slicing/image对象的resizeable ...

  4. QQ聊天界面的布局和设计(IOS篇)-第一季

    我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...

  5. 高仿qq聊天界面

    高仿qq聊天界面,给有需要的人,界面效果如下: 真心觉得做界面非常痛苦,给有需要的朋友. chat.xml <?xml version="1.0" encoding=&quo ...

  6. [转]Android:布局实例之模仿QQ登录界面

    Android:布局实例之模仿QQ登录界面 预览图: 准备: 1.找到模仿对象 QQ登陆界面UI下载>>>>> 2.导入工程 3.查看布局结构和使用控件 其对应效果图分布 ...

  7. 在WEB项目中调用QQ通讯组件打开QQ聊天界面

    在很多WEB项目中,需要提供在线服务的功能,加上自己的联系方式,例如:QQ,不用添加QQ好友也可以交谈,那这到底是怎么实现的呢? 对于这个功能,需要提到一个组件,即“QQ通讯组件”.QQ通讯组件是一种 ...

  8. Android—简单的仿QQ聊天界面

    最近仿照QQ聊天做了一个类似界面,先看下界面组成(画面不太美凑合凑合呗,,,,):

  9. JS简单仿QQ聊天工具的制作

    刚接触JS,对其充满了好奇,利用刚学到的一点知识,写了一个简单的仿QQ聊天的东西,其中还有很多的不足之处,有待慢慢提高. 功能:1.在输入框中输入内容,点击发送,即可在上方显示所输入内容. 2.点击‘ ...

随机推荐

  1. shell脚本语言与linux命令的联系与区别

    使用linux肯定是要会使用命令的,就算提供有用户界面,绝大部分功能还是要通过命令行去操作的.而shell脚本语言也是运行在linux上的脚本语言,对于服务器运维人员也是几乎必须要掌握的.而shell ...

  2. CD 基金会、Jenkins、Jenkins X、Spinnaker 和 Tekton 的常问问题

    转载:https://mp.weixin.qq.com/s/bQLqGrCM9NZYI0Njlu4N-w FAQ 什么是持续交付(CD)? CD是一种软件工程方法,团队在短周期内生成软件,确保软件可以 ...

  3. C# 使用Environment获取当前程序运行环境相关信息

    Enviroment类和AppDomain类前者表示系统级的相关信息,后者表示应用程序级的相关信息. 我常用这两个类获取一些程序运行目录.操作系统位数等信息: string basedir = App ...

  4. webpack4 css modules

    demo 代码点此,webpack4 中通过 css-loader 开启 css 模块化, 开始前先做点准备工作. 不了解 css 模块化的,可以前往查看github_css_modules. ##准 ...

  5. Linux服务器用postfix 发送邮件延迟 阻塞 被接收方拒绝等问题

    Linux服务器用postfix 发送邮件延迟 阻塞 被接收方拒绝等问题 postfix如何设置发送邮件延迟通知 1 */1 * * * /bin/bash /home/delete_postfix. ...

  6. 8 Best DDoS Attack Tools (Free DDoS Tool Of The Year 2019)

    #1) HULK Description: HULK stands for HTTP Unbearable Load King. It is a DoS attack tool for the web ...

  7. Java面向对象之泛型

    主要介绍: 认识泛型 构造方法中使用泛型 设置多个泛型 通配符 泛型接口 泛型方法 泛型数组 一.认识泛型 具体实例如下: package com.huolongluo.newfeatures; /* ...

  8. 结对编程-python实现

    目录 软件工程结对项目:Python实现wc程序 结对项目Github地址 项目成员 项目要求 说明 需求 PSP表格 解题思路描述 设计实现 代码组织图 代码分析 代码覆盖率 测试 单元测试 回归测 ...

  9. CI/CD DevOps

    CI/CD DevOps 通过技术工具链完成持续集成CI.持续交付CD.用户反馈和系统优化的整合,实现跨团队的无缝协作(DevOps). 什么是持续集成? 他是开发每天代码更新的副本,所有的开发工作都 ...

  10. 探究分析---利用sql批量更新部分时间的同比数据

    问题:如何将social_kol_tmp表 中的字段cost_YA中日期为201901-201909中的值替换为相同brand和pltform对应18年月份的col_cost字段的数据,其他日期的co ...