实现思维顺序:
1.首先我们需要准备2张.9的png图片(一张图片为左边聊天泡泡,一个图片为右边的聊天泡泡),可以使用draw9patch.bat工具制作,任何图片导入到drawable中。
2.需要写一个聊天室布局xml,布局由android.support.v7.widget.RecyclerView布局构成聊天信息列表布局,一个文本输入框作为信息输入,一个发送Button作为发送键。
3.需要写一个消息的子布局,用于显示RecyclerView布局中里的消息。
4.写一个保存数据的数据类,用于后续添加到List中
5.写一个形成布局需要使用的适配器类
6.在聊天室布局的activity的class中写入数据
1.首先我们需要准备2张.9的png图片
2.一个聊天室布局xml
<?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.support.v7.widget.RecyclerView android:id="@+id/chatroomRecyclerView" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/enter" android:layout_width="0dp" android:layout_height="wrap_content" android:hint="@string/contentHints" android:layout_weight="1" android:maxLines="2" /> <Button android:id="@+id/send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/send" /> </LinearLayout> </LinearLayout>
3.一个消息的子布局
<?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="wrap_content"> <LinearLayout android:id="@+id/left_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="left" android:background="@drawable/leftoo" > <TextView android:id="@+id/left_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" android:textColor="@color/colcrWhite" android:layout_margin="10dp"/> </LinearLayout> <LinearLayout android:id="@+id/right_layout" 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:gravity="center" android:textColor="@color/colcrWhite" android:layout_margin="10dp"/> </LinearLayout> </LinearLayout>
4.一个保存数据的类
package com.example.lenovo.mychatroom.data_processing; import java.util.Date; /** * Created by lenovo on 2018/5/4. */ /* 我们需要单例保存的数据为: 1.消息的内容; 2.消息的类型:发送还是接收; 3.消息创建时间 */ public class Msg { private String content; private int type; private String time; public final static int TYPE_RECEIVED=0; public final static int TYPE_SENT=1; public Msg(String content,int type){ this.content =content; this.type = type; this.time = timeData(); } public String getContent() { return content; } public int getType() { return type; } public String getTime() { return time; } /* 写一个获取时间的方法 */ public String timeData(){ Date date = new Date(); String timeData = String.format("%tH",date) +String.format("%tM",date) +String.format("%tS",date); return timeData; } }
5.一个形成布局需要使用的适配器类
package com.example.lenovo.mychatroom.data_processing; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.example.lenovo.mychatroom.R; import java.util.List; /** * Created by lenovo on 2018/5/4. */ /* 适配器类,注意适配器类中的泛型不是List集合而是Viewholder缓存内部类 */ public class MsgAdapter extends RecyclerView.Adapter<MsgAdapter.ViewHolder> { // 写一个从外部得到的List的全局变量。 private List<Msg> msgList; /* 缓存子布局的内部类 */ static class ViewHolder extends RecyclerView.ViewHolder{ View myView; LinearLayout left_layout; LinearLayout right_layout; TextView left_msg; TextView right_msg; public ViewHolder(View itemView) { super(itemView); myView = itemView; left_layout = (LinearLayout)itemView.findViewById(R.id.left_layout); right_layout = (LinearLayout)itemView.findViewById(R.id.right_layout); left_msg = (TextView)itemView.findViewById(R.id.left_msg); right_msg = (TextView)itemView.findViewById(R.id.right_msg); } } /* 传入外部list的构造方法 */ public MsgAdapter(List<Msg> msgList){ this.msgList = msgList; } /* 必须要重写的方法 将子布局填充到父类布局里,在将父类布局添加到缓存布局的内部类中,并且返回缓存布局内部类。 此处写RecyclerView布局的点击事件 */ @Override public MsgAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item,parent,false); final ViewHolder holder = new ViewHolder(view); holder.myView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int position = holder.getAdapterPosition();//得到当前点击的位置 Msg msg = msgList.get(position);//从点击位置里得到List中的单例 //从单例中得到时间 Toast.makeText(v.getContext(), "消息时间:"+msg.getTime(), Toast.LENGTH_SHORT).show(); } }); return holder; } /* 将布局数据导入到布局中的一个必须重写的方法 */ @Override public void onBindViewHolder(MsgAdapter.ViewHolder holder, int position) { Msg msg = msgList.get(position); //判断是信息是接收还是发送的,并且分别判断需要隐藏的布局和显示的布局 if (msg.getType() == Msg.TYPE_RECEIVED){ //判断到信息是接收的,将左边的布局显示,右边的布局隐藏 holder.left_layout.setVisibility(View.VISIBLE); holder.right_layout.setVisibility(View.GONE); holder.left_msg.setText(msg.getContent()); } if (msg.getType() == Msg.TYPE_SENT){ holder.right_layout.setVisibility(View.VISIBLE); holder.left_layout.setVisibility(View.GONE); holder.right_msg.setText(msg.getContent()); } } // 必须要重写的方法,返回list的长度 @Override public int getItemCount() { return msgList.size(); } }
6.在聊天室布局的activity的class中写入数据
package com.example.lenovo.mychatroom; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.Button; import android.widget.EditText; import com.example.lenovo.mychatroom.data_processing.Msg; import com.example.lenovo.mychatroom.data_processing.MsgAdapter; import java.util.ArrayList; import java.util.List; public class MyChatroomDemo extends AppCompatActivity { private List<Msg> msgList = new ArrayList<>(); private EditText editText; private Button sendButton; private RecyclerView recyclerView; private MsgAdapter msgAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_chatroom_demo); initMsgs(); editText = (EditText)findViewById(R.id.enter); sendButton = (Button)findViewById(R.id.send); recyclerView =(RecyclerView)findViewById(R.id.chatroomRecyclerView); //布局排列方式 LinearLayoutManager layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); msgAdapter = new MsgAdapter(msgList); recyclerView.setAdapter(msgAdapter); sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //得到输入框中的内容 String content = editText.getText().toString(); //判断内容不是空的 if(!"".equals(content)){ //将内容添加到单例中 Msg msg = new Msg(content,Msg.TYPE_SENT); msgList.add(msg); //要求适配器重新刷新 msgAdapter.notifyItemInserted(msgList.size()-1); //要求recyclerView布局将消息刷新 recyclerView.scrollToPosition(msgList.size()-1); editText.setText(""); } } }); } public void initMsgs(){ Msg msg1 = new Msg("你好!",Msg.TYPE_RECEIVED); msgList.add(msg1); Msg msg2 = new Msg("谢谢!你好。",Msg.TYPE_SENT); msgList.add(msg2); Msg msg3 = new Msg("加班么?",Msg.TYPE_RECEIVED); msgList.add(msg3); } }
实现的效果图: