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

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

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>
相关推荐
名明鸣冥几秒前
k8s-agent架构思考(一)
python
古法安卓6 分钟前
Android-SELinux 策略调试实战:从 AVC 日志到策略修复
android·java·android studio
SomeB1oody14 分钟前
【RustyML入门】5.2. 分类指标
开发语言·后端·机器学习·rust·教程
ZJU_统一阿萨姆32 分钟前
【推理优化进阶】图编译与运行时:动态形状、CUDA Graph 与内存规划
开发语言·人工智能·语言模型·架构·开源
@呱呱爱学习33 分钟前
C++大成之路_ STL容器_ Vector
开发语言·c++
码匠许师傅1 小时前
【C++ 面试真题】19. 聊聊 C++ 的迭代器
开发语言·c++·面试
AI情绪识别开源1 小时前
检信ALLEMOTION VibrationAI 2.4.0 12维度情绪识别开源源代码
开发语言·python
Dovis(誓平步青云)1 小时前
DevEco Studio 6.1.1 Windows 安装实录:从下载校验到首次启动
android·开发语言·数据库·人工智能·windows·harmonyos
qeen871 小时前
【数据结构】红黑树的算法原理解析与实现
开发语言·数据结构·c++·算法·红黑树
极创信息1 小时前
国产化信创适配认证高频术语:信创适配、软件自主可控、国产化率、代码溯源率、代码自主率、代码开源率是什么?
java·python·struts·eclipse·开源·php·hibernate