简单模仿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.点击‘ ...
随机推荐
- Autoware 培训笔记 No. 1——构建点云地图
1. 首记 相信许多刚开始玩无人驾驶的人都用过Autoware,对runtime manager都比较熟悉,虽然可以通过各种渠道了解到有些设置,甚至有些设置的app下参数的含义,但是,在真车的使用过程 ...
- 关于 ReadOnlySpan<T>
using System; using System.Linq; namespace BenchmarkAndSpanExample { public class NameParser { publi ...
- vs2017离线包下载安装并且不占用C盘空间使用教程
安装vs2017,前提是你的环境是.NET4.6,VS2017在下载好安装程序安装的时候,会根据你选择的功能模块来下载所需要的安装程序,微软.安卓和苹果等平台的SDK.模拟器和第三方扩展功能等会在用户 ...
- 『珂朵莉树 Old Driver Tree』
珂朵莉树 珂朵莉树其实不是树,只是一个借助平衡树实现的数据结构,主要是对于有区间赋值的数据结构题,可以用很暴力的代码很高效地完成任务,当然这是建立在数据随机的基础上的. 即使数据不是随机的,写一个珂朵 ...
- 『The Counting Problem 数位dp』
The Counting Problem Description 求 [L,R]内每个数码出现的次数. Input Format 若干行,一行两个正整数 L 和 R. 最后一行 L=R=0,表示输入结 ...
- java架构之路-(nginx使用详解)nginx的安装和基本配置
Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和Unix的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的Unix工具软件.应用程序和网络协议.它支持32位 ...
- convert datatable to List<T>
public class DataConvert { public static List<T> ConvertDataTable<T>(DataTable dt) { Lis ...
- GDAL读取Shapefile
-------------------------------------------------------------------------------------- #include < ...
- MVC 表格按树状形式显示 jstree jqgrid
1. 界面顯示 2.前端 jqgrid 代码 //加载表格 function GetGrid() { var selectedRowIndex = 0; var $gridTable = $('#gr ...
- 6 、 图论—NP 搜索
6.1 最大团 //最大团 //返回最大团大小和一个方案,传入图的大小 n 和邻接阵 mat //mat[i][j]为布尔量 #define MAXN 60 void clique(int n, in ...