简单模仿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.点击‘ ...
随机推荐
- 【Oracle】RMAN duplicate复制库
基础环境: 172.17.4.60 操作系统:Linux 6.4 数据库:Oracle11gR2 (源数据库) 172.17.4.61 操作系统:Linux 6.4 数据库:Oracle11gR2 ( ...
- .NET Core 2.1 以下的控制台应用程序生成 EXE,且使用命令行参数动态运行控制器应用程序的示例
文章: https://stackoverflow.com/questions/44038847/vs2017-compile-netcoreapp-as-exe 引用 <ItemGroup&g ...
- 解决前后端调用,跨域二次请求Access-Control-Max-Age
发现前后端分离的项目中,前端发起一个请求到后端,在Chrome浏览器下面debug的时候,Network下面看到同一个url有两条请求,url有两条请求,第一条请求的Method为OPTIONS,第二 ...
- [IDA] Oops! internal error 40343 occured.
问题描述: 解决方案: 安装 IDA 时,其路径下不要出现中文.
- 十七:迭代器模式详解(foreach的精髓)
定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示. 从定义中可以看出,迭代器模式是为了在不暴露该对象内部表示的情况下,提供一种顺序访问聚合对象中元素的方法.这种思想在JA ...
- gsoap工具生成wsdl接口 注意事项
wsdl是通过wsdl文件作为不同应用的通信接口,所以如何生成wsdl语言很重要,但是很多时候我们发现自己编写的头文件通过gsoap工具soapcpp2.exe从头文件中无法正常生成对应的wsdl语言 ...
- 在vue项目中通过iframe引入jquery项目
最近公司因为原来的jq框架存在的问题太多,所以要进行主题框架的重新搭建,我使用的vue进行的主题框架的重新搭建,但是原来的页面已经完成很多了,而且都是使用的jquery进行开发的 在vue中引入jqu ...
- Ubuntu启动器快捷方式文件解析
快捷方式名称 app_name.desktop 路径: /usr/share/applications/app_name.desktop # 简洁快捷方式格式 [Desktop Entry] Name ...
- 如何解决问题:程序无法正常启动(0xc0000022)
如何解决问题:程序无法正常启动(0xc0000022) 下文是由NeoSmart技术,通过全球网络上的工程师开发者和技术人员一起收集起来的信息,进行汇总并编辑而成的. 错误现象 该错误一般会通过警告, ...
- 其他综合-CentOS7 安装 Jumpserver 跳板机
CentOS7 安装 Jumpserver 跳板机 1.实验描述 搭建 jumpserver 平台,实现有效的运维安全审计.完美做到事先防范,事中控制和事后溯源 2.实验环境 物理机系统:Window ...