一个普通聊天页面的ui,以下图:android
##UI结构git
其中ListView的context layout 设计为包含左右两个TextView的设计,经过Adapter在显示消息时决定使用layout的哪一个TextView显示消息。github
左右两个TextView背景图(仿聊天气泡)ide
##界面布局(layout)布局
**activity_main.xml **ui
主界面this
<?xml version="1.0" encoding="utf-8"?> <!--采用LinearLayout布局 它包含的子控件将以横向或竖向的方式排列 android:orientation="vertical" 垂直排列--> <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:background="#d8e0e8" android:orientation="vertical" android:paddingBottom="16dp" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp" tools:context="study.zhukai.com.chatroom.MainActivity"> <!--ListView 该控件用来显示聊天消息,须要实现一个Adapter类配合--> <ListView android:id="@+id/msg_list_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:divider="#0000"> </ListView> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <!--消息输入框--> <EditText android:id="@+id/input_text" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:hint="Type Something" android:maxLines="2"/> <!--消息发送按钮--> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send"/> </LinearLayout> </LinearLayout>
msg_item.xml设计
ListView的content,实现消息放在聊天气泡的效果code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <!--位于左面的发送聊天气泡,android:background="@drawable/chat_send_bubble" 选择了聊天气泡的图片--> <LinearLayout android:id="@+id/left_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:background="@drawable/chat_send_bubble"> <TextView android:id="@+id/left_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" android:textColor="#fff"/> </LinearLayout> <!--位于右面的接受收聊天气泡--> <LinearLayout android:id="@+id/right_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:background="@drawable/chat_recv_bubble"> <TextView android:id="@+id/right_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" android:textColor="#fff"/> </LinearLayout> </LinearLayout>
##功能类实现xml
类结构
**MainActivity **
public class MainActivity extends Activity { private ListView msgListView; private EditText inputText; private Button send; private MsgAdapter adapter; private List<Msg> msgList =new ArrayList<Msg>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去除标题框 requestWindowFeature(Window.FEATURE_NO_TITLE); //选择布局文件 setContentView(R.layout.activity_main); //初始化几个消息 initMsgs(); adapter=new MsgAdapter(MainActivity.this,R.layout.msg_item,msgList); inputText = (EditText) findViewById(R.id.input_text); send =(Button) findViewById(R.id.send); msgListView =(ListView) findViewById(R.id.msg_list_view); msgListView.setAdapter(adapter); send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String content = inputText.getText().toString(); if(!"".equals(content)){ //设置消息类型(接受或发送) Msg msg =new Msg(content,Msg.TYPE_SENT); msgList.add(msg); //向adapter通知数据更新 adapter.notifyDataSetChanged(); //向adapter通知数据更新滚动到最新位置 msgListView.setSelection(msgList.size()); inputText.setText(""); } } }); } private void initMsgs(){ Msg msg1=new Msg("hello zhukai",Msg.TYPE_RECEIVED); Msg msg2=new Msg("nihao",Msg.TYPE_SENT); Msg msg3=new Msg("heihei",Msg.TYPE_RECEIVED); msgList.add(msg1); msgList.add(msg2); msgList.add(msg3); } }
Msg
public class Msg { public static final int TYPE_RECEIVED = 0; public static final int TYPE_SENT =1 ; private String content; private int type; public Msg(String content,int type){ this.content=content; this.type=type; } public String getContent(){ return content; } public int getType() { return type; } }
MsgAdapter
//ListView的配套Adapter类 public class MsgAdapter extends ArrayAdapter<Msg> { private int resourceId; //resourceId=ListView聊天气泡布局的xml文件id public MsgAdapter(Context context, int textViewResourceId, List<Msg> objects) { super(context, textViewResourceId, objects); resourceId= textViewResourceId; } //该方法决定在新消息到达后采用哪一种聊天气泡显示讯息 public View getView(int position, View convertView, ViewGroup parent) { Msg msg =getItem(position); View view; //自定义类 存放消息显示位置参数 ViewHolder viewHolder; if(convertView==null){ //经过LayoutInflater的inflate方法制造显示消息的view view = LayoutInflater.from(getContext()).inflate(resourceId,null); viewHolder=new ViewHolder(); //如下四句讲view的控件赋给viewHolder方便调用 viewHolder.leftLayout = (LinearLayout) view.findViewById(R.id.left_layout); viewHolder.rightLayout = (LinearLayout) view.findViewById(R.id.right_layout); viewHolder.leftMsg=(TextView) view.findViewById(R.id.left_msg); viewHolder.rightMsg= (TextView) view.findViewById(R.id.right_msg); view.setTag(viewHolder); }else{ view =convertView; viewHolder =(ViewHolder)view.getTag(); } //如下两句判断改用哪一种聊天气泡,不用的气泡设为不可见 if(msg.getType()==Msg.TYPE_RECEIVED){ viewHolder.leftLayout.setVisibility(View.VISIBLE); viewHolder.rightLayout.setVisibility(View.GONE); viewHolder.leftMsg.setText(msg.getContent()); }else if(msg.getType()==Msg.TYPE_SENT){ viewHolder.rightLayout.setVisibility(View.VISIBLE); viewHolder.leftLayout.setVisibility(View.GONE); viewHolder.rightMsg.setText(msg.getContent()); } return view; } class ViewHolder{ LinearLayout leftLayout; LinearLayout rightLayout; TextView leftMsg; TextView rightMsg; } }
代码地址:https://github.com/madkilly/MyAndroidStudy chatroom moudle