一、添加recyclerview依赖库之后,编辑xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chatrecyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/etcontent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/btnsend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"/>
</LinearLayout>
</LinearLayout>
二、定义消息的实体类,定义常量的关键字const,只有在单例类、companion object或者顶层方法中才可以使用
class MsgDatas(val msg:String,val type:Int ) {
companion object{
const val SENTMSG:Int=0
const val RECEIVERMSG:Int=1
}
}
三、Recyclerview的子布局
left
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_gravity="left"
android:layout_height="wrap_content"
android:textColor="#03A9F4"
android:id="@+id/tvleftitem"/>
</FrameLayout>
right
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_gravity="right"
android:layout_height="wrap_content"
android:textColor="#FF9800"
android:id="@+id/tvrightitem"/>
</FrameLayout>
四、Recyclerview的适配器:
class ChatAdapter(val msgList: List<MsgDatas>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
inner class LeftChatViewHolder(view: View): RecyclerView.ViewHolder(view) {
val textLeft:TextView=view.findViewById(R.id.tvleftitem)
}
inner class RightChatViewHolder(view: View): RecyclerView.ViewHolder(view) {
val textRight:TextView=view.findViewById(R.id.tvrightitem)
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerView.ViewHolder {
if (p1==MsgDatas.SENTMSG){
val view=LayoutInflater.from(p0.context).inflate(R.layout.msg_left_item,p0,false)
return LeftChatViewHolder(view)
}else{
val viewRight=LayoutInflater.from(p0.context).inflate(R.layout.msg_right_item,p0,false)
return RightChatViewHolder(viewRight)
}
}
override fun getItemCount(): Int {
return msgList.size
}
override fun onBindViewHolder(p0: RecyclerView.ViewHolder, p1: Int) {
val msg=msgList[p1]
when(p0){
is LeftChatViewHolder->{
p0.textLeft.setText(msg.msg)
}
is RightChatViewHolder ->{
p0.textRight.setText(msg.msg)
}
else -> throw IllegalArgumentException()
}
}
override fun getItemViewType(position: Int): Int {
val msg=msgList[position]
return msg.type
}
}
适配器根据不同的viewType创建不同的界面,getItemViewType方法返回当前position对应的消息类型
五、activity中的代码:
class ChatActivity:AppCompatActivity(),View.OnClickListener{
private val msgList=ArrayList<MsgDatas>()
private var adaper:ChatAdapter?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.chat_layout)
initData()
btnsend.setOnClickListener(this)
val layMannger= LinearLayoutManager(this)
chatrecyclerview.layoutManager=layMannger
adaper =ChatAdapter(msgList)
chatrecyclerview.adapter=adaper
}
override fun onClick(v: View?) {
when(v){
btnsend ->{
val content=etcontent.text.toString()
if (content.isNotEmpty()){
val msg=MsgDatas(content,MsgDatas.SENTMSG)
msgList.add(msg)
adaper?.notifyItemInserted(msgList.size-1)
etcontent.setText("")
}
}
}
}
private fun initData(){
val msg1=MsgDatas("hello,who are you",MsgDatas.SENTMSG)
msgList.add(msg1)
val msg2=MsgDatas("hello,who are you",MsgDatas.RECEIVERMSG)
msgList.add(msg2)
val msg3=MsgDatas("hello,who are you",MsgDatas.SENTMSG)
msgList.add(msg3)
}
}
如果想要好看的聊天背景,可以添加.9图片,此外这里调用适配器的notifyItemInserted()方法用于通知列表有新的数据插入,这样新增的数据才能在recyclerview中展现处理。你也可以调用适配器的notify DATaSetChanged()方法,将recyclerview中的所有元素刷新一次,这样不管是增加、删除还是修改元素,界面都会显示最新元素,缺点是效率低一些,如果数据多的情况,可以调用scrolltoposition()方法将显示的数据定位到最后一行,以保证一定能看到最后发的消息