UI界面编写实战

这里我们模拟QQ聊天的主界面,编写一个简单的聊天界面。

项目描述

首先搭建我们的主界面,在最上边放一个标题栏,然后是一个ListView,用于展示发送的消息,最下边是选择要发送的表情,内容类型,一个发送框和一个发送按钮。
先写一个颜色的资源

<?xml version="1.0" encoding="utf-8"?>
<resources><color name="light_blue">#18B4ED</color><color name="gray">#EBECEE</color><color name="white">#ffffff</color>
</resources>

然后就是主界面

<LinearLayout 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:orientation="vertical"tools:context=".MainActivity"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@color/light_blue"android:padding="15dp"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/jzw"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="20sp"android:textColor="@color/white"android:text="消息"/><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:textSize="25sp"android:textColor="@color/white"android:gravity="center"android:text="模拟聊天"/><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/login_icon01"/><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/personal_normal"android:layout_marginLeft="10dp"/></LinearLayout><ListViewandroid:id="@+id/listview"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:background="@drawable/chat_background"android:divider="#0000"></ListView><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:background="@color/gray"android:layout_margin="10dp"android:gravity="center"><ImageViewandroid:id="@+id/biaoqing"android:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/eol"/><ImageViewandroid:id="@+id/choose"android:layout_width="30dp"android:layout_height="30dp"android:src="@mipmap/addcommodity"android:layout_marginLeft="10dp"/><EditTextandroid:id="@+id/edittext"android:layout_width="0dp"android:layout_height="30dp"android:layout_weight="1"android:background="@color/white"android:layout_marginLeft="10dp"/><Buttonandroid:id="@+id/send"android:layout_width="wrap_content"android:layout_height="30dp"android:text="发送"android:background="@drawable/button"android:layout_marginLeft="10dp"/></LinearLayout>
</LinearLayout>

然后是我们的drawable文件的内容:
为发送按钮写了一个shape:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><corners android:radius="5dp"/><solid android:color="@color/light_blue"/>
</shape>

为展示消息的ListVeiw设置一个背景,也是用一个渐变色。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><gradientandroid:startColor="#ACE7EF"android:centerColor="#CAE0D9"android:endColor="#E7D9C5"android:angle="270"></gradient>
</shape>

为昵称前边的标签设置一个背景

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><corners android:radius="15dp"/><solid android:color="#86D070"/><padding android:left="20dp" android:right="20dp"/>
</shape>

接着,因为我们要发送和接收消息,让接收的消息呈现在左边,发送的消息呈现在右边,所以要为两边各写一个消息的布局。
左边的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/time"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:padding="10dp"android:text="星期五  14:29" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><ImageViewandroid:id="@+id/touxiang"android:layout_width="60dp"android:layout_height="60dp"android:src="@mipmap/weheartit" /><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/textbackground"android:text="营长"android:textColor="@color/white"android:textSize="15sp" /><TextViewandroid:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="16sp"android:text="美女"android:layout_marginLeft="10dp"/></LinearLayout><TextViewandroid:id="@+id/message"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="60sp"android:layout_marginTop="10sp"android:background="@mipmap/eng"/></LinearLayout></LinearLayout>
</LinearLayout>

右边的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/time"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:padding="10dp"android:text="星期五  14:29" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><LinearLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="right"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="right"android:orientation="horizontal"><TextViewandroid:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textSize="16sp"android:text="美女"android:layout_marginLeft="10dp"/><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/textbackground"android:text="营长"android:textColor="@color/white"android:textSize="15sp" /></LinearLayout><TextViewandroid:id="@+id/message"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="60sp"android:layout_marginTop="10sp"android:background="@mipmap/qqright"/></LinearLayout><ImageViewandroid:id="@+id/touxiang"android:layout_width="60dp"android:layout_height="60dp"android:src="@mipmap/weheartit" /></LinearLayout>
</LinearLayout>

接着定义我们消息内容的实体类ChatMessage.java

/*** Created by Administrator on 2015/8/31.*/
public class ChatMessage {private int touxiang;//头像private String title;//标签private String name;//昵称private String message;//消息内容private long time;//发送时间private int type;//消息类型,即左边或者右边public ChatMessage(int touxiang, String title, String name, String message, long time) {this.touxiang = touxiang;this.title = title;this.name = name;this.message = message;this.time = time;}public int getType() {return type;}public void setType(int type) {this.type = type;}public int getTouxiang() {return touxiang;}public void setTouxiang(int touxiang) {this.touxiang = touxiang;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public long getTime() {return time;}public void setTime(long time) {this.time = time;}
}

定义我们消息内容的适配器MessageAdapter

import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;/*** Created by Administrator on 2015/8/31.*/
public class MessageAdapter extends BaseAdapter{private LayoutInflater inflater;private ArrayList<ChatMessage> data;private Html.ImageGetter getter;private static final int TYPE=2;public static final int MESSAGE_LEFT=0;public static final int MESSAGE_RIGHT=1;public MessageAdapter(LayoutInflater inflater, ArrayList<ChatMessage> data,Html.ImageGetter getter) {this.inflater = inflater;this.data = data;this.getter=getter;}@Overridepublic int getViewTypeCount() {//得到当前缓存布局类型的数量return TYPE;//因为有左右两种布局,返回常量2}@Overridepublic int getItemViewType(int position) {return data.get(position).getType();//返回当前布局的类型}@Overridepublic int getCount() {return data.size();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ChatMessage chatMessage=data.get(position);View view=null;ViewHolder viewHolder;int type=getItemViewType(position);if(convertView==null){switch (type){case MESSAGE_LEFT:view=inflater.inflate(R.layout.message,null);break;case MESSAGE_RIGHT:view=inflater.inflate(R.layout.message_right,null);break;default:break;}viewHolder=new ViewHolder();viewHolder.touxiang= (ImageView) view.findViewById(R.id.touxiang);viewHolder.title= (TextView) view.findViewById(R.id.title);viewHolder.name= (TextView) view.findViewById(R.id.name);viewHolder.message= (TextView) view.findViewById(R.id.message);viewHolder.time= (TextView) view.findViewById(R.id.time);view.setTag(viewHolder);}else {view=convertView;viewHolder= (ViewHolder) view.getTag();}viewHolder.touxiang.setImageResource(chatMessage.getTouxiang());viewHolder.title.setText(chatMessage.getTitle());viewHolder.name.setText(chatMessage.getName());Spanned spanned=Html.fromHtml(chatMessage.getMessage(),getter,null);viewHolder.message.setText(spanned);//因为内容可能添加表情,所以传入富文本SimpleDateFormat format= new SimpleDateFormat("EEE HH:mm");String time=format.format(new Date(chatMessage.getTime()));viewHolder.time.setText(time);//设置显示时间的格式return view;}class ViewHolder{ImageView touxiang;TextView title;TextView name;TextView message;TextView time;}
}

下面就要设置表情了,我们点击表情图片时,弹出一个PopupWindow,然后在里边设置一个GridView来显示我们的全部表情。
新建一个Gridview布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><GridViewandroid:id="@+id/expression"android:layout_width="match_parent"android:layout_height="match_parent"android:numColumns="4"></GridView>
</LinearLayout>

然后是表情的布局,就是一个ImageView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"><ImageViewandroid:id="@+id/image_expression"android:layout_width="wrap_content"android:layout_height="wrap_content" />
</LinearLayout>

然后我们定义表情的实体类Expression

/*** Created by Administrator on 2015/8/31.*/
public class Expression {private int image;//设置一张表情的图片public int getImage() {return image;}public void setImage(int image) {this.image = image;}
}

接着我们写一个表情的适配器ExpressionAdapter

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import java.util.ArrayList;/*** Created by Administrator on 2015/8/31.*/
public class ExpressionAdapter extends BaseAdapter {private LayoutInflater inflater;private ArrayList<Expression> expressions;public ExpressionAdapter(LayoutInflater inflater, ArrayList<Expression> expressions) {this.inflater = inflater;this.expressions = expressions;}@Overridepublic int getCount() {return expressions.size();}@Overridepublic Object getItem(int position) {return position;}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Expression expression=expressions.get(position);View view =inflater.inflate(R.layout.biaoqing,null);ImageView image= (ImageView) view.findViewById(R.id.image_expression);image.setImageResource(expression.getImage());return view;}
}

接下来呢,为了美观,当我们点击加号图片时,弹出一个PopupWindow,里边放置两个RadioButton,让我们选择发送信息的类型。
定义这个布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="horizontal"><RadioGroupandroid:id="@+id/radiogroup"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><RadioButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="receive"/><RadioButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="send"/></RadioGroup>
</LinearLayout>

最后就是我们主活动的代码了!

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import java.util.ArrayList;public class MainActivity extends Activity {private EditText editText;private ArrayList<ChatMessage> data;private MessageAdapter adapter;private Html.ImageGetter getter;private ListView listView;private LayoutInflater inflater;private GridView gridView;private ArrayList<Expression> expressions;private ExpressionAdapter expressionAdapter;private View view;private View chooseView;private ImageView imageView;private ImageView choose;private String name;private ChatMessage chatMessage;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText = (EditText) findViewById(R.id.edittext);imageView = (ImageView) findViewById(R.id.biaoqing);choose = (ImageView) findViewById(R.id.choose);Button send = (Button) findViewById(R.id.send);listView = (ListView) findViewById(R.id.listview);inflater = getLayoutInflater();view = inflater.inflate(R.layout.expression, null);chooseView = inflater.inflate(R.layout.sendreceive, null);data = new ArrayList<>();imageView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {PopupWindow popupWindow = new PopupWindow(MainActivity.this);popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);popupWindow.setContentView(view);popupWindow.setFocusable(true);popupWindow.setOutsideTouchable(true);popupWindow.update();popupWindow.showAtLocation(view, Gravity.CENTER, 0, 400);}});gridView = (GridView) view.findViewById(R.id.expression);expressions = new ArrayList<>();initExpression();expressionAdapter = new ExpressionAdapter(inflater, expressions);getter = new Html.ImageGetter() {@Overridepublic Drawable getDrawable(String source) {Drawable drawable = getResources().getDrawable(Integer.parseInt(source));drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());return drawable;}};gridView.setAdapter(expressionAdapter);gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {Spanned spanned = Html.fromHtml("<img src='" + expressions.get(position).getImage() + "'/>", getter, null);//将表情插入到光标所在位置editText.getText().insert(editText.getSelectionStart(), spanned);}});choose.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {PopupWindow popupWindow = new PopupWindow(MainActivity.this);popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);popupWindow.setContentView(chooseView);popupWindow.setFocusable(true);popupWindow.setOutsideTouchable(true);popupWindow.update();popupWindow.showAtLocation(view, Gravity.CENTER, 0, 450);}});RadioGroup radioGroup = (RadioGroup) chooseView.findViewById(R.id.radiogroup);radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup group, int checkedId) {RadioButton radioButton = (RadioButton) chooseView.findViewById(checkedId);name = (String) radioButton.getText();}});send.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (name.equals("send")) {String message = filterHtml(Html.toHtml(editText.getText()));chatMessage = new ChatMessage(R.mipmap.weheartit, "老大", "巴黎铁塔前的黎明", message, System.currentTimeMillis());chatMessage.setType(MessageAdapter.MESSAGE_RIGHT);} else if (name.equals("receive")) {String message = filterHtml(Html.toHtml(editText.getText()));chatMessage = new ChatMessage(R.mipmap.weheartit, "老二", "东京樱花后的黄昏", message, System.currentTimeMillis());chatMessage.setType(MessageAdapter.MESSAGE_LEFT);}data.add(chatMessage);adapter.notifyDataSetChanged();listView.setSelection(data.size());//将ListView定位到最后一行editText.setText("");//清空输入框的内容}});adapter = new MessageAdapter(inflater, data, getter);listView.setAdapter(adapter);}/*** 将文本转化为HTML格式后,发送的时候去掉除富文本以外的内容** @param str 转化为HTML格式的字符串* @return 富文本*/public String filterHtml(String str) {str = str.replaceAll("<(?!br|img)[^>]+>", "").trim();return str;}/***初始化表情*/private void initExpression() {Expression expression1 = new Expression();expression1.setImage(R.mipmap.ebg);expressions.add(expression1);Expression expression2 = new Expression();expression2.setImage(R.mipmap.ebh);expressions.add(expression2);Expression expression3 = new Expression();expression3.setImage(R.mipmap.ebl);expressions.add(expression3);Expression expression4 = new Expression();expression4.setImage(R.mipmap.ebo);expressions.add(expression4);Expression expression5 = new Expression();expression5.setImage(R.mipmap.ebw);expressions.add(expression5);Expression expression6 = new Expression();expression6.setImage(R.mipmap.eca);expressions.add(expression6);Expression expression7 = new Expression();expression7.setImage(R.mipmap.ecb);expressions.add(expression7);Expression expression8 = new Expression();expression8.setImage(R.mipmap.ecc);expressions.add(expression8);Expression expression9 = new Expression();expression9.setImage(R.mipmap.eew);expressions.add(expression9);}
}

好了,至此大功告成!让我们测试一下结果吧!
##运行结果:
首先是我们的界面

然后点击加号,选择我们要发送的类型,选择send

输入发送内容,点击表情,选择要发送的表情

点击发送

最后的效果:

UI界面编写(仿QQ聊天界面)相关推荐

  1. Android 仿qq聊天界面之一

    一.登录界面 本来是只想仿一个qq的聊天界面的,顺便做了一个登录界面,熟悉下SharedPreferences(解释一下:SharedPreferences由于非常适合记录一些零散的简单的数据,因此登 ...

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

    最近仿照QQ聊天做了一个类似界面,先看下界面组成(画面不太美凑合凑合呗,,,,): 其中聊天背景可以是一个LinearLayout或者RelativeLayout里面存放的是ListView(将Lis ...

  3. php仿qq聊天界面,jquery仿微信聊天界面

    首先看一下我们的效果图. 这个颜色可能搭配的有些不合适,但基本功能大都实现了.就是你和你同桌对话,你发的消息在你的左侧,而在他设备的右侧. 首先先写好整体的框架,在一个大容器中放两个盒子,分别是左侧和 ...

  4. 仿QQ聊天软件(登录界面、好友界面、聊天界面)-Java(Swing、Socket)

    文章目录 一.项目结构 二.项目功能 三.制作界面 (一).登录界面的制作 (二).好友列表界面 (三).聊天界面 四.制作服务器 五.设计通信协议 六.项目缺点 学习了socket通信后,就想来制作 ...

  5. 高仿微信聊天界面长按弹框样式

    效果图 背景 在公司做的项目里面,刚好有需要用到微信聊天界面长按弹框样式这种UI的. 网上找了一下,没找到. Android现成的 ListPopupWindow又不能满足需求. 因此在非上班时间撸一 ...

  6. android 仿微信聊天界面 以及语音录制功能,Android仿微信录制语音功能

    本文实例为大家分享了Android仿微信录制语音的具体代码,供大家参考,具体内容如下 前言 我把录音分成了两部分 1.UI界面,弹窗读秒 2.一个类(包含开始.停止.创建文件名功能) 第一部分 由于6 ...

  7. android自定义设置界面,Android开发之精仿QQ设置界面(自定义PreferenceActivity)

    Android开发之精仿QQ设置界面(自定义PreferenceActivity) 时间:2011-12-05 10:25:06 来源:Android开发者门户 作者: 今天,再给大家分享一下QQ设置 ...

  8. 使用js实现的带输入状态的简单的仿微信聊天界面

    使用js实现的简单的仿微信聊天界面,实现固定的聊天回复功能,只能是固定的5句,但是回复的内容可以在代码的判断中进行修改. 实现的效果有:1.实现仿微信的聊天界面 2.实现仿微信的正在输入功能. 原理: ...

  9. C语言实现类似QQ聊天界面抖动功能

    该博文为原创文章,未经博主同意不得转载,如同意转载请注明博文出处 本文章博客地址:https://cplusplus.blog.csdn.net/article/details/104991863 实 ...

最新文章

  1. python爬虫项目-23个Python爬虫开源项目代码
  2. python以下是变量合法命名的是_Python超级详细的变量命名规则
  3. 如何在SAP Business by design的UI上扩展新的按钮
  4. iOS: How To Make AutoLayout Work On A ScrollView
  5. Codeforces Round #674 (Div. 3)
  6. vue点击切换类名_vue 新用户引导(vue-dirver)
  7. java+cache使用方法_java相关:springboot使用GuavaCache做简单缓存处理的方法
  8. iphone字体大小设置_Win10电脑桌面上使用的记事本便签软件字体大小怎么调整?...
  9. SpaceBase – 基于 Sass 的响应式 CSS 框架
  10. Spring自动注解装配、自动检测装配Bean配合过滤组件使用
  11. oracle在cmd中启动数据库实例
  12. java基础——李兴华视频
  13. HighNewTech:19.04.22今天GitHub后无来者大事件之【B站后端代码不小心被开源】
  14. Lua:小数精度计算,几位数判断,四舍五入,最靠近5倍数取整
  15. Android Studio调用百度地图(二):实现地图显示后台定位和步行导航
  16. uniapp实现音视频通讯
  17. 【Java】抽象类继承的综合案例
  18. python爬虫淘宝实例-python 淘宝爬虫示例源码(抓取天猫数据)
  19. C语言知识点总结:指针
  20. wrong ELF class: ELFCLASS32

热门文章

  1. 天津理工计算机专业中外合作,天津理工大学中外合作办学硕士国外合作院校及专业...
  2. win10下php + apache客户端上传文件
  3. c语言多变量输入,技多不压身——C语言(五)变量,常量和输入输出
  4. 元宇宙产业委与南京信息工程大学举办“元宇宙与智能技术创新论坛”
  5. 2023上半年软考各省份报名时间已公布!
  6. LongAdder原理分析和性能测试
  7. MOS管常用驱动电路
  8. SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
  9. Unreal Engine 4 使用HLSL自定义着色器(Custom Shaders)教程(下)
  10. App地推活动需要做哪些准备 - Xinstall