安卓实现左右布局聊天界面

先看效果图。是不是你们想要的。大概就是这样的效果

Android 实现左右布局聊天界面(好友左、自己右)

采用 RecyclerView + 双布局 Item 实现,结构清晰、可直接复用,适配聊天气泡样式。

一、整体思路

两种 Item 布局:

item_msg_left.xml:对方消息(居左)

item_msg_right.xml:自己消息(居右)

消息实体类:记录消息内容、发送者类型

RecyclerView 适配器:根据类型加载不同布局

气泡背景:自带圆角、区分左右样式

二、1. 消息实体类 MsgBean

java 复制代码
public class MsgBean {
    // 消息文本
    private String content;
    // 0=对方消息(左)  1=自己消息(右)
    private int msgType;

    public MsgBean(String content, int msgType) {
        this.content = content;
        this.msgType = msgType;
    }

    // getter & setter
    public String getContent() {
        return content;
    }

    public int getMsgType() {
        return msgType;
    }
}

三、2. 左边 Item 布局(对方消息)item_msg_left.xml

java 复制代码
<?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:padding="10dp"
    android:gravity="left">

    <TextView
        android:id="@+id/tv_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:maxWidth="250dp"
        android:textColor="#333333"
        android:background="@drawable/bg_msg_left"/>

</LinearLayout>
  1. 右边 Item 布局(自己消息)item_msg_right.xml
java 复制代码
<?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:padding="10dp"
    android:gravity="right">

    <TextView
        android:id="@+id/tv_msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:maxWidth="250dp"
        android:textColor="#FFFFFF"
        android:background="@drawable/bg_msg_right"/>

</LinearLayout>

四、4. 气泡背景 drawable

bg_msg_left.xml(左侧灰色气泡)

java 复制代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#E5E5E5"/>
    <corners
        android:topLeftRadius="5dp"
        android:topRightRadius="15dp"
        android:bottomLeftRadius="15dp"
        android:bottomRightRadius="15dp"/>
</shape>

bg_msg_right.xml(右侧蓝色气泡)

java 复制代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#0099FF"/>
    <corners
        android:topLeftRadius="15dp"
        android:topRightRadius="5dp"
        android:bottomLeftRadius="15dp"
        android:bottomRightRadius="15dp"/>
</shape>

五、5. RecyclerView 适配器 MsgAdapter

java 复制代码
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;

public class MsgAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final List<MsgBean> msgList;
    // 区分两种布局类型
    private static final int TYPE_LEFT = 0;
    private static final int TYPE_RIGHT = 1;

    public MsgAdapter(List<MsgBean> msgList) {
        this.msgList = msgList;
    }

    // 根据消息类型返回布局
    @Override
    public int getItemViewType(int position) {
        return msgList.get(position).getMsgType();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == TYPE_LEFT) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_msg_left, parent, false);
            return new LeftHolder(view);
        } else {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_msg_right, parent, false);
            return new RightHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        MsgBean bean = msgList.get(position);
        if (holder instanceof LeftHolder) {
            ((LeftHolder) holder).tvMsg.setText(bean.getContent());
        } else if (holder instanceof RightHolder) {
            ((RightHolder) holder).tvMsg.setText(bean.getContent());
        }
    }

    @Override
    public int getItemCount() {
        return msgList.size();
    }

    // 左边ViewHolder
    static class LeftHolder extends RecyclerView.ViewHolder {
        TextView tvMsg;
        public LeftHolder(@NonNull View itemView) {
            super(itemView);
            tvMsg = itemView.findViewById(R.id.tv_msg);
        }
    }

    // 右边ViewHolder
    static class RightHolder extends RecyclerView.ViewHolder {
        TextView tvMsg;
        public RightHolder(@NonNull View itemView) {
            super(itemView);
            tvMsg = itemView.findViewById(R.id.tv_msg);
        }
    }

    // 添加消息 + 自动滚动到底部
    public void addMsg(MsgBean bean) {
        msgList.add(bean);
        notifyItemInserted(msgList.size() - 1);
    }
}

六、6. 主界面布局 activity_chat.xml

java 复制代码
<?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">

    <!-- 聊天列表 -->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_chat"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <!-- 输入栏 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="8dp">

        <EditText
            android:id="@+id/et_input"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="输入消息"/>

        <Button
            android:id="@+id/btn_send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="发送"/>

    </LinearLayout>

</LinearLayout>

七、7. 聊天 Activity 逻辑 ChatActivity.java

java 复制代码
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;

public class ChatActivity extends AppCompatActivity {

    private RecyclerView recyclerChat;
    private EditText etInput;
    private MsgAdapter msgAdapter;
    private List<MsgBean> msgList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        recyclerChat = findViewById(R.id.recycler_chat);
        etInput = findViewById(R.id.et_input);
        Button btnSend = findViewById(R.id.btn_send);

        // 初始化列表
        msgList = new ArrayList<>();
        msgAdapter = new MsgAdapter(msgList);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerChat.setLayoutManager(layoutManager);
        recyclerChat.setAdapter(msgAdapter);

        // 模拟对方默认消息
        msgAdapter.addMsg(new MsgBean("你好呀", 0));

        // 发送按钮点击
        btnSend.setOnClickListener(v -> {
            String content = etInput.getText().toString().trim();
            if (!content.isEmpty()) {
                // 添加自己消息(右)
                msgAdapter.addMsg(new MsgBean(content, 1));
                etInput.setText("");
                // 自动滚动到底部
                recyclerChat.scrollToPosition(msgAdapter.getItemCount() - 1);
            }
        });
    }
}

效果说明

1.好友消息:左侧灰色气泡

2.自己消息:右侧蓝色气泡

3.发送消息自动滚到底部

4.消息最大宽度限制,长文本自动换行

八、软键盘弹出自动上移聊天列表(安卓聊天界面必备)

默认情况下:弹出输入法键盘时,RecyclerView 聊天列表不会往上顶,输入框会被键盘遮挡、最新消息被键盘盖住看不到。

软键盘弹起 → 整个聊天布局自动上移

最新消息自动显示在键盘上方,不会被遮挡

AndroidManifest.xml 配置(最简单,一行搞定)

找到你的 ChatActivity 对应的 activity 标签,添加属性:

xml 复制代码
android:windowSoftInputMode="adjustResize"

完整示例:

xml 复制代码
<activity
    android:name=".ChatActivity"
    android:windowSoftInputMode="adjustResize">
</activity>
相关推荐
xier_ran1 天前
【infra之路】PagedAttention
java·开发语言
Irissgwe1 天前
十、LangGraph能力详解:工作流的常见模式
python·langchain·ai编程·工作流·langgraph
Merlyn101 天前
【栈】155. 最小栈
python·算法
SilentSamsara1 天前
NumPy 进阶:广播机制、ufunc 与向量化计算的工程实践
开发语言·python·青少年编程·性能优化·numpy
林爷万福1 天前
机器学习在光谱分析中的应用:Python实现
人工智能·python·机器学习
珊瑚里的鱼1 天前
C++的强制类型转换
android·开发语言·c++
编程探索者小陈1 天前
接口自动化三件套:JSON Schema 校验 + logging 日志 + Allure 测试报告
开发语言·python
godspeed_lucip1 天前
LLM和Agent——专题6:Multi Agent 入门(3)
人工智能·python
星恒随风1 天前
C++ 类和对象入门(二):默认成员函数、构造函数和析构函数详解
开发语言·c++·笔记·学习
摇滚侠1 天前
JavaWeb 全套教程 乱码问题 85-88
java·开发语言