简单模仿QQ聊天界面
首先看一下最终的效果,显示了消息时间,用户昵称,用户头像。

大致实现方法:
用最简单的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聊天界面的更多相关文章
- QQ聊天界面的布局和设计(IOS篇)-第二季
QQChat Layout - 第二季 本来第二季是快写好了, 也花了点功夫, 结果gitbook出了点问题, 给没掉了.有些细节可能会一带而过, 如有疑问, 相互交流进步~. 在第一季中我们完成了Q ...
- Qt 之 模仿 QQ登陆界面——样式篇
一.简述 今天晚上花了半天时间从QQ登录界面抠了些图,顺便加了点样式基本上实现了QQ的登陆界面全部效果.虽不说100%相似,那也有99.99%相似了哈O(∩_∩)O. QQ好像从去年开始,登录界面有了 ...
- Objective-c——UI基础开发第八天(QQ聊天界面)
一.知识点: QQ聊天界面 双模型的使用(dataModel和frameModel) UITextField的使用 通知的使用 拉伸图片的两种方法(slicing/image对象的resizeable ...
- QQ聊天界面的布局和设计(IOS篇)-第一季
我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...
- 高仿qq聊天界面
高仿qq聊天界面,给有需要的人,界面效果如下: 真心觉得做界面非常痛苦,给有需要的朋友. chat.xml <?xml version="1.0" encoding=&quo ...
- [转]Android:布局实例之模仿QQ登录界面
Android:布局实例之模仿QQ登录界面 预览图: 准备: 1.找到模仿对象 QQ登陆界面UI下载>>>>> 2.导入工程 3.查看布局结构和使用控件 其对应效果图分布 ...
- 在WEB项目中调用QQ通讯组件打开QQ聊天界面
在很多WEB项目中,需要提供在线服务的功能,加上自己的联系方式,例如:QQ,不用添加QQ好友也可以交谈,那这到底是怎么实现的呢? 对于这个功能,需要提到一个组件,即“QQ通讯组件”.QQ通讯组件是一种 ...
- Android—简单的仿QQ聊天界面
最近仿照QQ聊天做了一个类似界面,先看下界面组成(画面不太美凑合凑合呗,,,,):
- JS简单仿QQ聊天工具的制作
刚接触JS,对其充满了好奇,利用刚学到的一点知识,写了一个简单的仿QQ聊天的东西,其中还有很多的不足之处,有待慢慢提高. 功能:1.在输入框中输入内容,点击发送,即可在上方显示所输入内容. 2.点击‘ ...
随机推荐
- Kubernetes 弹性伸缩全场景解读(二)- HPA 的原理与演进
前言 在上一篇文章 Kubernetes 弹性伸缩全场景解析 (一):概念延伸与组件布局中,我们介绍了在 Kubernetes 在处理弹性伸缩时的设计理念以及相关组件的布局,在今天这篇文章中,会为大家 ...
- 2019-3-20-UWP-How-to-custom-RichTextBlock-right-click-menu
原文:2019-3-20-UWP-How-to-custom-RichTextBlock-right-click-menu title author date CreateTime categorie ...
- 查询SAP系统支持的ABAP版本
7.52可以使用select 内表,但是怎么看版本呢? 如果有在开发中用到ABAP 7.4&7.5个版本的新语法时,需要考虑到系统支持的ABAP版本,那么要怎么查看呢? 其实这个和SAP的内核 ...
- sqlserver the name is not a valid identifier error in function
参考资料:https://stackoverflow.com/questions/22008859/the-name-is-not-a-valid-identifier-error-in-functi ...
- 机器学习实战:基于Scikit-Learn和TensorFlow 第5章 支持向量机 学习笔记(硬间隔)
数据挖掘作业,需要实现支持向量机进行分类,记录学习记录 环境:win10,Python 3.7.0 SVM的基本思想:在类别之间拟合可能的最宽的间距,也叫作最大间隔分类 书上提供的源代码绘制了两个图, ...
- 关于BFS+异或(C++)
今天早上,我们做了场比赛,里面有一个题目是这样的.. 题目大意: 随着马场的繁荣,出现了越来越多的新马种.种族之间的沟通不畅严重影响了马场的和谐.这时,科学家发明了马语翻译机器人,正好可 ...
- DevExpress的TreeList怎样设置数据源使其显示成单列树形结构
场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...
- Linux文件共享服务 FTP,NFS 和 Samba
Linux 系统中,存储设主要有下面几种: DAS DAS 指 Direct Attached Storage,即直连附加存储,这种设备直接连接到计算机主板总线上,计算机将其识别为一个块设备,例如常见 ...
- 8个有意思的JavaScript面试题
摘要: 神奇的JS系列. 作者:前端小智 原文:8个问题看你是否真的懂 JS Fundebug经授权转载,版权归原作者所有. JavaScript 是一种有趣的语言,我们都喜欢它,因为它的性质.浏览器 ...
- Java内存模型。
Java内存模型: 准备知识:缓存,缓存一致性,硬件缓冲区:写缓冲区.无效化队列,内存重排序,内存屏障. 1.Java内存模型概念. 首先,在并发的情况下,计算机系统必须解决这样两个问题:第一,一个处 ...