Android:实现QQ聊天(超简单)

前言

1. 简单定义Msg类

package com.bytedance.sjtu.msg

class Msg(val msg: String, val msgType: Int) {

    companion object {
        const val SEND = 0  //定义消息类型,0为发送, 1为收取
        const val GET = 1
    }

}

2. ChatActivity

class ChatActivity : AppCompatActivity() {

    private val tvName : TextView by lazy { findViewById(R.id.tvName) }
    private val recyclerView : RecyclerView by lazy { findViewById(R.id.recyclerView) }
    private val editMsg : EditText by lazy { findViewById(R.id.editMsg) }
    private val sendMsg : TextView by lazy { findViewById(R.id.sendMsg) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_chat)
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)   //设置隐藏状态栏

        val msgList = mutableListOf(
            Msg( "你好", Msg.SEND),
            Msg( "嗯嗯", Msg.GET),
            Msg( "How are you?", Msg.SEND),
            Msg( "I'm fine, thanks.", Msg.GET),
            )
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = ChatAdapter(this, msgList)  //简单初始化聊天信息

        editMsg.addTextChangedListener(object : TextWatcher {  //监听消息输入框的输入状态
            override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }
            override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
            }
            override fun afterTextChanged(p0: Editable?) {
                if (editMsg.text.isNotEmpty()) {
                    sendMsg.setTextColor(resources.getColor(R.color.silver_red))  //输入框有内容,发布字体变红色
                } else {
                    sendMsg.setTextColor(resources.getColor(R.color.light_gray))  //否则变灰色
                }
            }
        })
        
        sendMsg.setOnClickListener {
            if (editMsg.text.isNotEmpty()) {
                val msgType = Random.nextInt(0, 2)  //随机生成 0 和 1
                msgList.add(Msg(editMsg.text.toString(), msgType))  //模拟“发送消息”和“接收消息”
                recyclerView.adapter = ChatAdapter(this, msgList)  //更新适配器数据
                recyclerView.scrollToPosition(msgList.size - 6)
                recyclerView.smoothScrollBy(0, 1000, DecelerateInterpolator(), 1500)  //平滑刷新消息界面,有bug
                editMsg.text = null  //输入框置空
            }
        }
    }
}

3. activity_chat.XML布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="true"
    tools:context=".msg.ChatActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <ImageView
            android:id="@+id/imgBack"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginStart="5dp"
            android:padding="15dp"
            android:src="@drawable/ic_back" />

        <TextView
            android:id="@+id/tvName"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:gravity="center"
            android:text="name"
            android:textSize="20sp"
            android:textColor="@color/black" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.1dp"
            android:layout_gravity="bottom"
            android:background="@color/light_gray" />

    </FrameLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:background="#EAEDF6" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/editMsg"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:layout_margin="10dp"
            android:padding="12dp"
            android:hint="输入..."
            android:textSize="18sp"
            android:background="@drawable/bg_round_rectangle_2" />

        <TextView
            android:id="@+id/sendMsg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginEnd="10dp"
            android:layout_marginBottom="10dp"
            android:text="发送"
            android:textStyle="bold"
            android:textSize="20sp"
            android:textColor="@color/light_gray" />

    </LinearLayout>

</LinearLayout>

4. ChatAdapter适配器

class ChatAdapter(
    private val mContext: Context,
    private val msgList: MutableList<Msg>
): RecyclerView.Adapter<ChatAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_chat_item_view, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {  //绑定数据
        if (msgList[position].msgType == Msg.SEND) {  //发出的消息
            holder.msgSend.text = msgList[position].msg
            holder.msgSend.visibility = View.VISIBLE
            holder.msgGet.visibility = View.GONE
        } else if (msgList[position].msgType == Msg.GET) {  //收到的消息
            holder.msgGet.text = msgList[position].msg
            holder.msgGet.visibility = View.VISIBLE
            holder.msgSend.visibility = View.GONE
        }

        holder.itemView.setOnClickListener {
//            Toast.makeText(mContext, "You click msg $position", Toast.LENGTH_SHORT).show()
        }
    }

    override fun getItemCount(): Int {
        return msgList.size
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val msgSend : TextView = itemView.findViewById(R.id.msgSend)
        val msgGet : TextView = itemView.findViewById(R.id.msgGet)
    }

}

5. layout_chat_item_view.XML布局文件

其中TextView的background应该设置为9-Patch文件,也就是.9.png文件,可以自己制作。
在这里插入图片描述
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginHorizontal="10dp">

    <TextView
        android:id="@+id/msgSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="25dp"
        android:layout_gravity="end"
        android:text="这是发送的消息"
        android:textSize="18sp"
        android:textColor="@color/white"
        android:background="@drawable/bg_bubble_1_50" />

    <TextView
        android:id="@+id/msgGet"
        android:gravity="start"
        android:visibility="visible"
        android:background="@drawable/bg_bubble_2_50"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="25dp"
        android:text="这是收到的消息"
        android:textSize="18sp"
        android:textColor="@color/black" />


</FrameLayout>
  • 1
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leekey_sjtu

我们一起从小白开始加油~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值