admin管理员组文章数量:1656270
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/apk/res/android"
xmlns:tools="http://schemas.android/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/light_blue"
android:padding="15dp"
>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/jzw"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="@color/white"
android:text="消息"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="25sp"
android:textColor="@color/white"
android:gravity="center"
android:text="模拟聊天"
/>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/login_icon01"
/>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/personal_normal"
android:layout_marginLeft="10dp"
/>
</LinearLayout>
<ListView
android: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>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/gray"
android:layout_margin="10dp"
android:gravity="center">
<ImageView
android:id="@+id/biaoqing"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/eol"/>
<ImageView
android:id="@+id/choose"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@mipmap/addcommodity"
android:layout_marginLeft="10dp"/>
<EditText
android:id="@+id/edittext"
android:layout_width="0dp"
android:layout_height="30dp"
android:layout_weight="1"
android:background="@color/white"
android:layout_marginLeft="10dp"/>
<Button
android: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/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/apk/res/android">
<gradient
android: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/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/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="星期五 14:29" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/touxiang"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/weheartit" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android: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" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="美女"
android:layout_marginLeft="10dp"/>
</LinearLayout>
<TextView
android: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/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="10dp"
android:text="星期五 14:29" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="horizontal">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="美女"
android:layout_marginLeft="10dp"/>
<TextView
android: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>
<TextView
android: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>
<ImageView
android: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;
}
@Override
public int getViewTypeCount() {//得到当前缓存布局类型的数量
return TYPE;//因为有左右两种布局,返回常量2
}
@Override
public int getItemViewType(int position) {
return data.get(position).getType();//返回当前布局的类型
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public 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/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<GridView
android: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/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android: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;
}
@Override
public int getCount() {
return expressions.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public 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/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<RadioGroup
android:id="@+id/radiogroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="receive"/>
<RadioButton
android: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;
@Override
protected 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
RadioButton radioButton = (RadioButton) chooseView.findViewById(checkedId);
name = (String) radioButton.getText();
}
});
send.setOnClickListener(new View.OnClickListener() {
@Override
public 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聊天界面) 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1729734007a1211596.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论