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

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

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>
相关推荐
程序猿乐锅4 分钟前
【从0-1学习Python | 第六篇】 Python 函数:定义、参数与返回值
开发语言·python·学习
G018_star sky♬6 分钟前
java中的字符串常见方法
java·开发语言
熊猫钓鱼>_>8 分钟前
Kotlin Multiplatform for OpenHarmony 实战:kotlinx-serialization JSON 适配
开发语言·华为·kotlin·华为云·json·harmonyos·code
MasonYyp1 小时前
声音转文字的模型
python
银河技术1 小时前
从脚本到 Operator:用 Go 构建可靠的微服务自动扩缩容控制器
开发语言·微服务·golang
GIS数据转换器3 小时前
地下空间综合管廊运营管理平台
大数据·开发语言·人工智能·经验分享·perl
Wang's Blog8 小时前
Java 项目实战: 交友项目:登录链路回顾与今日任务地图
java·开发语言·状态模式·交友
信誓旦旦的程序猿9 小时前
【Python量化实战宝典 #08】可转债与债券接口手册:转股价·溢价率·纯债价值(Python 可跑)
java·python·股票数据api·股票数据api接口·股票api数据接口·股票量化数据api·股票量化数据接口
砚底藏山河9 小时前
python量化:行情数据回溯
java·开发语言·python·金融·maven
今年下半年9 小时前
AI智能体项目实战记录(02):初始化 Python 项目
开发语言·人工智能·python·fastapi