Android : 编写精美的聊天界面

2023-05-16

Android 编写精美的聊天界面

  • 1、准备工作
  • 2、编写精美的聊天界面
  • 参考

1、准备工作

首先制作一张 .9 格式的聊天气泡;

需要注意的是,制作完成后,应该将原始文件删除,否则AS会分不清楚而报错。

新建一个 Empty Activity,Java 和 XML 文件的命名分别为 MainActivity.java 和 activity_main.xml;

2、编写精美的聊天界面

首先编写主界面,修改 activity_main.xml 中的代码,如下所示:

<?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"
    android:padding="10dp"
    android:background="#d8e0e8">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/msg_recycler_view"
        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:layout_marginTop="5dp"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/input_text"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:hint="Type message here"
            android:textAllCaps="false"
            android:maxLines="2"
            android:gravity="left"/>

        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Send"
            android:textAllCaps="false"
            android:textSize="20sp"/>
    </LinearLayout>

</LinearLayout>

我们在主界面中放置了一个 RecyclerView 用于显示聊天的消息内容;又放置了一个 EditText 用于输入消息,还放置了一个 Button 用于发送消息;然后,定义消息的实体类,新建 Msg.java,代码如下:

public class Msg {
    public static final int TYPE_RECEIVED = 0;
    public static final int TYPE_SEND = 1;
    private String content;
    private int type;

    public Msg(String content,int type){
        this.content = content;
        this.type = type;
    }

    public String getContent() {
        return content;
    }

    public int getType() {
        return type;
    }

Msg 类中只有两个字段:

  • content 表示消息的内容
  • type 表示消息的类型;

其中消息的类型有两个可选值:

  • TYPE_RECEIVED 表示这是一条收到的消息
  • TYPE_SEND 表示这是一条发出的消息

接下来编写 RecyclerView 子项的布局,新建 msg_item.xml 文件,添加代码如下:

<?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:orientation="vertical">

    <LinearLayout
        android:id="@+id/left_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:orientation="vertical"
        android:background="@drawable/message_left">

        <TextView
            android:id="@+id/left_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            android:textColor="@color/black"/>

    </LinearLayout>

    <LinearLayout
        android:id="@+id/right_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:orientation="vertical"
        android:background="@drawable/message_left">

        <TextView
            android:id="@+id/right_msg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="10dp"
            android:textColor="@color/black"/>

    </LinearLayout>
</LinearLayout>

这里我们让收到的消息居左对齐,发出的消息居右对其;并且使用 message_left.9 作为聊天气泡;接下来需要创建 RecyclerView 的适配器类,新建 MsgAdapter.java,添加代码如下:

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

    private List<Msg> list;
    public MsgAdapter(List<Msg> list){
        this.list = list;
    }
    static class ViewHolder extends RecyclerView.ViewHolder{
        LinearLayout leftLayout;
        TextView left_msg;

        LinearLayout rightLayout;
        TextView right_msg;

        public ViewHolder(View view){
            super(view);
            leftLayout = view.findViewById(R.id.left_layout);
            left_msg = view.findViewById(R.id.left_msg);

            rightLayout = view.findViewById(R.id.right_layout);
            right_msg = view.findViewById(R.id.right_msg);
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.msg_item,parent,false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Msg msg = list.get(position);
        if(msg.getType() == Msg.TYPE_RECEIVED){
            //如果是收到的消息,则显示左边的消息布局,将右边的消息布局隐藏
            holder.leftLayout.setVisibility(View.VISIBLE);
            holder.left_msg.setText(msg.getContent());

            //注意此处隐藏右面的消息布局用的是 View.GONE
            holder.rightLayout.setVisibility(View.GONE);
        }else if(msg.getType() == Msg.TYPE_SEND){
            //如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏
            holder.rightLayout.setVisibility(View.VISIBLE);
            holder.right_msg.setText(msg.getContent());

            //同样使用View.GONE
            holder.leftLayout.setVisibility(View.GONE);
        }
    }

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

最后修改 MainActivity.java 中的代码,来为 RecyclerView 初始化一些数据,并给发送按钮加入事件响应;代码如下:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private List<Msg> msgList = new ArrayList<>();
    private RecyclerView msgRecyclerView;
    private EditText inputText;
    private Button send;
    private LinearLayoutManager layoutManager;
    private MsgAdapter adapter;

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

        msgRecyclerView = findViewById(R.id.msg_recycler_view);
        inputText = findViewById(R.id.input_text);
        send = findViewById(R.id.send);
        layoutManager = new LinearLayoutManager(this);
        adapter = new MsgAdapter(msgList = getData());

        msgRecyclerView.setLayoutManager(layoutManager);
        msgRecyclerView.setAdapter(adapter);

/*       我们还需要为button建立一个监听器,我们需要将编辑框的内容发送到 RecyclerView 上:
            ①获取内容,将需要发送的消息添加到 List 当中去。
            ②调用适配器的notifyItemInserted方法,通知有新的数据加入了,赶紧将这个数据加到 RecyclerView 上面去。
            ③调用RecyclerView的scrollToPosition方法,以保证一定可以看的到最后发出的一条消息。*/
        send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String content = inputText.getText().toString();
                if(!content.equals("")) {
                    msgList.add(new Msg(content,Msg.TYPE_SEND));
                    adapter.notifyItemInserted(msgList.size()-1);
                    msgRecyclerView.scrollToPosition(msgList.size()-1);
                    inputText.setText("");//清空输入框中的内容
                }
//                自定义一问一答
                if(msgList.size() == 2){
                    msgList.add(new Msg("What's your name?",Msg.TYPE_RECEIVED));
                    adapter.notifyItemInserted(msgList.size()-1);
                    msgRecyclerView.scrollToPosition(msgList.size()-1);
                }
                if(msgList.size() == 4){
                    msgList.add(new Msg("Nice to meet you,Bye!",Msg.TYPE_RECEIVED));
                    adapter.notifyItemInserted(msgList.size()-1);
                    msgRecyclerView.scrollToPosition(msgList.size()-1);
                }
            }
        });
    }

    private List<Msg> getData(){
        List<Msg> list = new ArrayList<>();
        list.add(new Msg("Hello",Msg.TYPE_RECEIVED));
        return list;
   }
}

在这里插入图片描述

参考

1、https://www.cnblogs.com/hyacinthLJP/p/14352840.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android : 编写精美的聊天界面 的相关文章

  • 线程、进程、并发、cpu、gpu的联系

    1 线程和进程的区别 进程 xff1a 一个在内存中运行的应用程序 每个进程都有自己独立的一块内存空间 xff0c 一个进程可以有多个线程 比如在Windows系统中 xff0c 一个运行的xx exe就是一个进程 线程 xff1a 进程中
  • ubuntu系统安装cuda、cudnn、pytorch和libtorch

    1 安装cuda和cudnn 本机安装的cuda版本11 0 2 cudnn版本 v8 0 5 cu11 0 Ubuntu20 04下CUDA cuDNN的详细安装与配置过程 xff08 图文 xff09 ubuntu20 04安装cuda
  • 深度学习语法篇

    一 基本常识 图像的分辨率的通道数 分辨率和通道数是两个不同的概念 分辨率指的是图像的像素数量 xff0c 它反映了图像的清晰度和细节程度 例如 xff0c 一个分辨率为64x64的图像意味着它有64个像素行和64个像素列 xff0c 总共
  • 第二讲:线性表示及坐标

    第二讲 xff1a 线性表示及坐标 一 线性表示 1 线性表示定义 xff1a 设 是线性空间V中的向量 xff0c 若存在V中一组向量 1 xff0c 2 xff0c xff0c n xff0c 及一组数x1 xff0c x2 xff0c
  • 快速理解掌握指针

    p gt next 61 q 像这种语句 xff0c 表示改变了p后面的连接关系 p 61 q gt next 这类语句 xff0c 没改变连接关系 xff0c 只是赋值而已 解读代码中指针所代表的节点之间的前后连接关系 只要输出该指针对应
  • 第三讲:子空间

    第三讲 xff1a 子空间 一 子空间定义 1 子空间 xff1a 设V是数域F上的线性空间 xff0c W是V的子集 xff0c 若对W中的任意元素 xff0c 及数K F xff0c 按V中的加法和数乘有 xff1a 1 xff09 4
  • Qt多线程之线程之间的传递数据

    hpp span class token macro property span class token directive keyword ifndef span MAINWINDOW H span span class token ma
  • 循环队列c代码实现

    循环队列的抽象数据类型 ADT 队列 xff08 Queue xff09 Data 同线性表 元素具有相同的类型 xff0c 相邻元素具有前驱和后继的关系 Operator span class token function InitQue
  • CMake(四):变量

    前面展示了如何定义基本目标和生成构建输出 就其本身而言 xff0c 这已经很有用了 xff0c 但CMake还附带了一大堆其他特性 xff0c 这些特性带来了极大的灵活性和便利性 本章涵盖了CMake最基本的部分之一 xff0c 即变量的使
  • CMake(六):使用子目录

    对于简单的项目 xff0c 将所有内容保存在一个目录中是可以的 xff0c 但是大多数实际项目倾向于将它们的文件分割到多个目录中 通常可以找到不同的文件类型或分组在各自的目录下的独立模块 xff0c 或者将属于逻辑功能组的文件放在项目目录层
  • CMake(九):生成器表达式

    当运行CMake时 xff0c 开发人员倾向于认为它是一个简单的步骤 xff0c 需要读取项目的CMakeLists txt文件 xff0c 并生成相关的特定于生成器的项目文件集 例如Visual Studio解决方案和项目文件 xff0c
  • CNNs系列---AlexNet网络介绍

    CNNs系列 AlexNet介绍 导言AlexNet介绍1 网络结构 1 参数量 计算量和输出尺寸计算公式 2 网络参数解析 2 AlexNet中涉及到的知识点 1 基本概念 2 AlexNet网络结构的贡献 导言 我们将开启关于卷积神经网
  • CNNS:基于AlexNet的分类任务

    CNNS 基于AlexNet的分类任务 数据集介绍1 pokeman数据集介绍2 flower数据集介绍 超参数对模型的影响1 激活函数对模型的影响 1 使用 96 Sigmoid 96 进行训练 2 使用 96 tanh 96 进行训练
  • CNNs: AlexNet补充

    CNNs AlexNet的补充 导言对 96 AlexNet 96 模型进行调整模型不同层的表征其他探索总结 导言 上上篇和上一篇我们详细地讲述了AlexNet的网络结构和不同超参数对同一数据集的不同实验现象 本节 xff0c 我们就Ale
  • 解决“Permission denied, please try again.”的问题

    在Ubuntu的终端输入命令 ssh highlight highlight是本地主机名称提示输入用户密码 当密码输入正确时 xff0c 仍返回错误 xff1a Permission denied please try again 解决的办
  • leetcode学习常用网站

    C 43 43 网站 cplusplus com map find C 43 43 Reference github com leopeng1995 acplusplus Morris Traversal方法遍历二叉树 xff08 非递归
  • arctan对照表

    注 xff1a 实际调用的是C 43 43 的atan2接口 arctan y x resultstd cout lt lt atan2 0 1 lt lt std endl 0std cout lt lt atan2 0 707 0 70
  • 关于optimized out

    根据网络上的说法 xff0c 调试期间如果一个变量的值显示 optimized out xff0c 那么就表明编译器将该变量进行了优化 xff0c 导致其值不可见 解决的方法是 xff0c 设置编译优化选项 xff0c 禁止相关的优化 可以
  • Ubuntu命令行中重复执行一个程序

    以下示例中 xff0c 执行program 10次 xff0c 并将运行日志以追加的方式重定向到log txt文件中 xff0c progam的入口参数是param for i in 1 10 do program param gt gt
  • 技术知识库

    我对自动控制技术发展趋势的理解 对数学理论的运用越来越深入 xff0c 对计算机的依赖越来越高 xff1b 与人们生产生活的契合越来越紧密以至于无法分割 xff1b 越来越向人类思维的本质倾向 心想事成靠拢 xff0c 让少数人的大脑和肢体

随机推荐