最近心血来潮,打算实现一个很久之前就想实现的一个界面,就是聊天界面,当时觉得好高大上啊,完全不会啊,不过最近不小心找到了方法。
效果图
本来是想上传一张动态图的,但是不知道怎么回事,半天传不上去,只好上传一张静态图了。
效果解析:在底部输入框里面输入文字信息,点击左边的按钮,就会是左边的消息发布,
点击右边的按钮,就是右边发的消息,当消息发布出去以后,新的消息会出现的最下面
实现方式
其实实现原理很简单,真不知道当初我为什么没有想到。
首先需要知道的是,这个界面是用的什么布局,布局确定好了,基本就成功一半了,因为在代码部分的代码真的很少很简单。
首先是主界面,好吧,其实也就一个界面,消息显示的区域主要是用的listview,下面2个按钮一个输入框就很好实现了。
布局文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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=".activity.MainActivity">
<ListView
android:divider="@null"
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"></ListView>
<TextView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#898989" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<Button
android:id="@+id/btn_left"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_margin="5dp"
android:background="@drawable/btn_float"
android:text="左边"
android:textColor="#fff" />
<EditText
android:id="@+id/et_meg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:id="@+id/btn_right"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_margin="5dp"
android:background="@drawable/btn_float"
android:text="右边"
android:textColor="#fff" />
</LinearLayout>
</LinearLayout>
这样就能实现主界面的布局。
之后就是listview的item布局,刚开始还不知道怎么写,而且还遇到了一些小问题,不过这些小问题,后来都解决了
布局文件:item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/boy" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:text="鸣人" />
</LinearLayout>
<TextView
android:id="@+id/text_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:background="@drawable/left"
android:text="" />
</LinearLayout>
<LinearLayout
android:id="@+id/right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/text_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/right"
android:text="" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/girl" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="静香" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
布局文件有点长,直接给张图片看清楚,相信你一定可以根据图片写出相应的布局。
解析:将一个文字域和一个头像放在一个线性布局中,创建两个线性布局,一个在左一个在右,注意,此时这两个线性布局都是在同一行
既然是listview,当然少不了实体类和adapter
首先来实体类:MsgInfo
其实这个类只有两个数据,一个是左边的消息,一个是右边的消息
private String left_text;
private String right_text;
用get和set方法封装一下就好了。
记得别忘了构造方法:
public MsgInfo(String left_text, String right_text) {
this.left_text = left_text;
this.right_text = right_text;
}
接下来是adapter,我们重写一个adapter继承BaseAdapter类
public class ListviewAdapter extends BaseAdapter {
private Context context;
private List<MsgInfo> datas = new ArrayList<>();
private ViewHolder viewHolder;
//给adapter添加数据
public void addDataToAdapter(MsgInfo e) {
datas.add(e);
}
public ListviewAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return datas.size();
}
@Override
public Object getItem(int position) {
return datas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
//使用viewholder来优化listview
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.item, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//获取adapter中的数据
String left = datas.get(position).getLeft_text();
String right = datas.get(position).getRight_text();
//如果数据为空,则将数据设置给右边,同时显示右边,隐藏左边
if (left == null) {
viewHolder.text_right.setText(right);
viewHolder.right.setVisibility(View.VISIBLE);
viewHolder.left.setVisibility(View.INVISIBLE);
}
//与上一步相反
if (right == null) {
viewHolder.text_left.setText(left);
viewHolder.left.setVisibility(View.VISIBLE);
viewHolder.right.setVisibility(View.INVISIBLE);
}
return convertView;
}
public static class ViewHolder {
public View rootView;
public TextView text_left;
public LinearLayout left;
public TextView text_right;
public LinearLayout right;
public ViewHolder(View rootView) {
this.rootView = rootView;
this.text_left = (TextView) rootView.findViewById(R.id.text_left);
this.left = (LinearLayout) rootView.findViewById(R.id.left);
this.text_right = (TextView) rootView.findViewById(R.id.text_right);
this.right = (LinearLayout) rootView.findViewById(R.id.right);
}
}
}
文件名:MainActivity
各种绑定控件之后,给两个按钮设置监听事件:
Override
public void onClick(View v) {
String msg = et_meg.getText().toString().trim();
switch (v.getId()) {
case R.id.btn_left:
adapter.addDataToAdapter(new MsgInfo(msg,null));
adapter.notifyDataSetChanged();
break;
case R.id.btn_right:
adapter.addDataToAdapter(new MsgInfo(null, msg));
adapter.notifyDataSetChanged();
break;
}
listview.smoothScrollToPosition(listview.getCount() - 1);
et_meg.setText("");
}
大功告成!接下来就开始享受鸣人和静香的跨次元交流之旅吧(^ _ ^!)
注:item布局中的textview的背景图片为点9图片。