一、前言以及效果图:
这是一个简单的聊天界面,类似于QQ聊天的界面那样如下图:
不过没人家那么高大上咯。毕竟作为一个新手的我还在路上奔跑,效果图就是上图所示了,接下来我们看看是怎么实现的。
二、实现代码
1.因为在布局中我么使用的是RecycleView控件,所以首先要在app/build.grade里面添加依赖库,代码如下:
dependencies { ... compile 'com.android.support:recyclerview-v7:26.1.0' ... }
2.接下来我们定义一个消息的实体类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; } }
3. 修改activity_main.xml文件,在父布局中先放一个RecyclerView控件,在其下面添加一个子布局,放一个EditText和Button分别是消息输入框和发送按钮,代码如下:
<?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:background="#d8e0e8" > <android.support.v7.widget.RecyclerView android:id="@+id/mRv" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:layout_marginTop="5dp" android:layout_marginRight="5dp" android:layout_marginLeft="5dp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:layout_marginTop="5dp"> <EditText android:id="@+id/mEt" 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" android:textAllCaps="false"/> </LinearLayout> </LinearLayout>
4. 还需要写一个布局作为RecyclerView子项布局,新建布局文件msg_item.xml,代码如下:
<?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="wrap_content" android:orientation="vertical" android:padding="10dp"> <LinearLayout android:id="@+id/layout_left" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:background="@drawable/message_left"> <TextView android:id="@+id/left_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:textColor="#fff" /> </LinearLayout> <LinearLayout android:id="@+id/layout_right" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:layout_marginTop="3dp" android:background="@drawable/message_right"> <TextView android:id="@+id/right_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="5dp" android:textColor="#000" /> </LinearLayout> </LinearLayout>
这里我们把左右消息框都显示了出来,我们需要在代码中根据消息的类型将另外一个消息的布局隐藏掉就OK了。代码见第5步。
5. 然后我们需要创建一个RecyclerView的适配器,代码如下:
public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder>{ private List<Msg> mMsgLIst; //内部类 static class ViewHolder extends RecyclerView.ViewHolder{ LinearLayout leftLayout; LinearLayout rightLayout; TextView leftMsg; TextView rightMsg; //找到子项布局中的控件 public ViewHolder(View view){ super(view); leftLayout = (LinearLayout) view.findViewById ( R.id.layout_left ); rightLayout = (LinearLayout) view.findViewById ( R.id.layout_right ); leftMsg = (TextView) view.findViewById ( R.id.left_msg ); rightMsg = (TextView) view.findViewById ( R.id.right_msg ); } } //构造函数,用于把要展示的数据源传递进来 public MsgAdapter(List<Msg> msgLIst){ mMsgLIst = msgLIst; } //加载子项布局,返回一个View @Override public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType){ View view = LayoutInflater.from ( parent.getContext ()) .inflate(R.layout.msg_item,parent,false); return new ViewHolder ( view ); } //对子项中的数据赋值函数 @Override public void onBindViewHolder(ViewHolder holder,int position){ Msg msg = mMsgLIst.get ( position );//得到msg实例 if (msg.getType()==Msg.TYPE_RECEIVED){//表示收到消息 holder.leftLayout.setVisibility ( View.VISIBLE );//显示左边的消息布局 holder.rightLayout.setVisibility ( View.GONE );//隐藏右边的消息布局 holder.leftMsg.setText ( msg.getContent () ); }else if (msg.getType()==Msg.TYPE_SENT){ holder.rightLayout.setVisibility ( View.VISIBLE ); holder.leftLayout.setVisibility ( View.GONE ); holder.rightMsg.setText ( msg.getContent () ); } } @Override public int getItemCount(){ return mMsgLIst.size (); } }
6. 最后就是MainActivity主代码了,
public class MainActivity extends AppCompatActivity { private List<Msg> msgList = new ArrayList<> ( ); private EditText mEt; private Button send; private RecyclerView mRv; private MsgAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate ( savedInstanceState ); setContentView ( R.layout.activity_main ); initMsg();//初始化消息数据 mEt = findViewById ( R.id.mEt ); send = findViewById ( R.id.send ); mRv = findViewById ( R.id.mRv ); //建立数据和RecyclerView之间的联系 LinearLayoutManager layoutManager = new LinearLayoutManager ( this); mRv.setLayoutManager ( layoutManager );//制定RecyclerView的布局方式 adapter = new MsgAdapter ( msgList );//将数据传递到MsgAdapter构造函数中 mRv.setAdapter ( adapter ); send.setOnClickListener ( new View.OnClickListener () { @Override public void onClick(View view) { String content = mEt.getText ().toString (); if(!"".equals ( content )){//如果输入框不为空,就执行以下内容 Msg msg = new Msg ( content,Msg.TYPE_SENT ); msgList.add ( msg ); adapter.notifyItemInserted (msgList.size ()-1); mRv.scrollToPosition ( msgList.size ()-1 );//将显示的数据定位到 最后一行 mEt.setText ( "" );//点击发送后清空输入框的内容 } } } ); } private void initMsg(){ Msg msg1 = new Msg ( "在吗?",Msg.TYPE_RECEIVED ); msgList.add ( msg1 );//将msg1加入到列表msgList中 Msg msg2 = new Msg ( "在,你是哪位?",Msg.TYPE_SENT ); msgList.add ( msg2 ); Msg msg3 = new Msg ( "我是你爸爸。",Msg.TYPE_RECEIVED ); msgList.add ( msg3 ); } }
这样一个简单的聊天界面就完成了。