您的位置:首页 > 移动开发 > Android开发

android学习笔记——聊天界面的练习

2015-12-10 21:27 381 查看
想象一下,最简单的聊天界面里面需要的有哪些?
1、一个ListView来显示对话信息
2、底部需要一个EditText来输入信息,还要一个Button来点击发送。
好了,根据以上的想法先将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:background="#d8e0e8"

android:orientation="vertical"

>

<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 here"

android:maxLines="2"/>

<Button

android:id="@+id/send"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Send"/>

</LinearLayout>

</LinearLayout>

写好主界面的布局后,我们把消息的实体类写一下。
消息分为两种,一种是发出的,一种是收到的,所以我们将消息实体设计成这样:

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;
}
}

消息的实体类有了,我们需要将实体放在View上才能看的到,这是就得好好想想msg_item.xml这个文件该怎么写了。就是它要填充到主界面中ListView的每一个item中去。既然消息分两种,那么显示的View自然也是需要两种的。看看布局文件是怎么写的。

<?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"

android:padding="10dp">

<LinearLayout

android:id="@+id/left_layout"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="left"

android:background="@drawable/left">

<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="#000"/>

</LinearLayout>

<LinearLayout

android:id="@+id/right_layout"

android:layout_marginLeft="200dp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="right"

android:background="@drawable/right">

<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="#000"/>

</LinearLayout>
</LinearLayout>

这个时候就有些疑惑了,怎么能让收到和发送的信息布局放到同一个布局文件里呢?别担心,还记得可见属性么?
我们在代码中根据发送还是接收进行一个判断,然后设置相应的可见性,问题不就解决了吗?
但是,到底该在哪里写这些代码呢?
答案就是Adapter,可以肯定的一点,Adapter的作用就是将view与数据进行绑定的工具,它与布局中的每个组件联系紧密,就是在这里,我们需要判断数据到底该使用哪个布局,是发送呢?还是接收呢?
看看代码

public class MsgAdapter extends ArrayAdapter<Msg> {

private int resourceId;

public MsgAdapter(Context context,int textViewResourceId, List<Msg> objects) {

super(context,textViewResourceId, objects);

resourceId = textViewResourceId;

}

一点一点来讲解,别急。
创建ListView的适配器类,让它继承ArrayAdapter,并将泛型指定为Msg类。新建类MsgAdapter。
上面的代码中,resourceId是为了获取当前View的ID,方便一会使用,进行一个绑定。

@Override

public View getView(int position, View convertView, ViewGroup parent) {

Msg msg = getItem(position);
View view;
ViewHolder viewHolder;//还记得ViewHolder吧,他是一个内部类,方便在View已经存在的情况下使用该布局,只需要getTag(viewHolder)就可以咯

if(convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId,null);//在这里使用resourceId来对view进行绑定,修改。

viewHolder = new 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();
}
//以上,我们使用ViewHolder给view进行了页面的布局绑定,之后我们只需要对ViewHolder中的内容进行操作,view中的内容也会随之跟着改变。很方便有木有!

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.leftLayout.setVisibility(View.GONE);

viewHolder.rightLayout.setVisibility(View.VISIBLE);

viewHolder.rightMsg.setText(msg.getContent());
}
//上述对消息实体类进行了判断,然后设置不同的显示/隐藏。使用viewHolder,很方便吧,代码也简介明了了很多。

return view;
//最后当然还是要返回view,给主活动使用。

}

class ViewHolder{

LinearLayout leftLayout;

LinearLayout rightLayout;

TextView leftMsg;

TextView rightMsg;

}
}

把上面的这些事都干完后,回到主活动中来。仔细想想好像在主活动中要做的事情已经没多少了。
1、把消息实体初始化一下
2、给主活动的页面初始化一下(加载写好的ListView这个布局)
3、给设置下Button的点击事件,让输入框中的内容发送出去。
好,那我们就开始吧~

1.将消息实体初始化

public void initMsgs(){

Msg msg1 = new Msg("Hello guys",Msg.TYPE_RECEIVED);

msgList.add(msg1);

Msg msg2 = new Msg("Hello Who is there?",Msg.TYPE_SENT);

msgList.add(msg2);

Msg msg3 = new Msg("I am tom ,Nice talking to you",Msg.TYPE_RECEIVED);

msgList.add(msg3);
}
看上述代码,其实要做的只有两件事:1.创建一个Msg对象,传入两个参数,参数1是消息信息,参数2是消息类型。2.将创建出的Msg对象加入到msgList列表中去。

2.给主活动的页面初始化一下(加载写好的ListView这儿布局)
adapter = new MsgAdapter(MainActivity.this,R.layout.msg_item,msgList);//在adapter中绑定好数据和组件
msgListView = (ListView) findViewById(R.id.msg_list_view);

msgListView.setAdapter(adapter)//给msgListView设置Adapter

3.设置Button的点击事件,让输入框中的内容发送出去

inputText = (EditText) findViewById(R.id.input_text);

send = (Button) findViewById(R.id.send);

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.notifyDataSetChanged();//当有新消息时,刷新ListView中的显示

msgListView.setSelection(msgList.size());//将ListView定位到最后一行

inputText.setText("");//清空输入框中的内容

}

}
});
至此,所有的工作就做完了。同学们可以试试看啦~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: