首页 > 编程语言 >仿微信聊天程序 - 05. 聊天列表

仿微信聊天程序 - 05. 聊天列表

时间:2023-07-16 13:44:42浏览次数:31  
标签:05 fx 列表 item 聊天 background 仿微信 public color

本文是仿微信聊天程序专栏的第五篇文章,主要记录了【聊天列表】的界面实现。

界面设计

聊天列表在主界面左边,主要显示最近的聊天记录,以及添加好友的信息等,总体界面设计如下:

界面布局

聊天列表的布局分为两部,列表布局和列表中的每一行的布局,其中列表布局的完整fxml如下:

<HBox prefHeight="640.0"
      prefWidth="250.0" xmlns:fx="http://javafx.com/fxml"
      stylesheets="@ChatListController.css"
      fx:controller="michong.javafx.wx.view.chat.ChatListController">
    <children>
        <VBox prefWidth="250.0">
            <children>
                <HBox prefHeight="70.0" prefWidth="200.0" spacing="10.0">
                    <children>
                        <TextField prefHeight="30.0" HBox.hgrow="ALWAYS" promptText="聊天搜索"/>
                        <Button prefHeight="30.0" prefWidth="30.0" text="+" onAction="#onApplyClick"/>
                    </children>
                    <padding>
                        <Insets left="10.0" right="10.0" top="20.0"/>
                    </padding>
                </HBox>
                <ListView fx:id="chatListView" VBox.vgrow="ALWAYS"/>
            </children>
        </VBox>
    </children>
</HBox>

列表项的布局完整fxml如下:

<HBox xmlns:fx="http://javafx.com/fxml" stylesheets="@ChatRowController.css" alignment="CENTER" prefHeight="60.0"
      prefWidth="235.0"
      spacing="5.0"
      fx:id="chatRowHBox">
    <children>
        <Pane prefHeight="60.0" prefWidth="48.0">
            <children>
                <ImageView fx:id="avatarImageView" fitHeight="40.0" fitWidth="40.0" layoutX="5.0" layoutY="10.0"/>
                <Label fx:id="messageCountLabel" layoutX="35.0" prefHeight="20.0" styleClass="message-count-label"/>
            </children>
        </Pane>
        <VBox prefWidth="116.0" spacing="4.0" HBox.hgrow="ALWAYS">
            <children>
                <Label fx:id="nicknameLabel" styleClass="name-label"/>
                <Label fx:id="messageLabel" styleClass="message-label"/>
            </children>
            <padding>
                <Insets bottom="5.0" left="5.0" right="5.0" top="8.0"/>
            </padding>
        </VBox>
        <VBox alignment="TOP_RIGHT" prefWidth="85.0">
            <children>
                <Label fx:id="timestampLabel" styleClass="timestamp-label"/>
            </children>
            <padding>
                <Insets bottom="5.0" left="5.0" right="5.0" top="10.0"/>
            </padding>
        </VBox>
    </children>
</HBox>

构建控件

从上面的界面布局中可以看到列表项并没有直接关联Controller,因为这里我实现动态构建,所以在初始化的时候绑定Controller,具体实现如下:


/**
 * @author michong
 */
public class ChatRowController extends ListCell<MessageVO> {

    public HBox chatRowHBox;
    public ImageView avatarImageView;
    public Label messageCountLabel;
    public Label nicknameLabel;
    public Label messageLabel;
    public Label timestampLabel;

    FXMLLoader loader;

    @Override
    protected void updateItem(MessageVO item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || Objects.isNull(item)) {
            setGraphic(null);
            return;
        }

        if (Objects.isNull(loader)) {
            loader = new FXMLLoader(getClass().getResource("/" + getClass().getName().replace(".", "/") + ".fxml"));
            loader.setController(this);
            try {
                loader.load();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        if (item.getSource() == MessageSource.APPLY) {
            avatarImageView.setImage(FXAvatar.apply());
            nicknameLabel.setText("新朋友");
            messageLabel.setText(item.getNickname() + " 申请添加你为好友。");
        } else {
            avatarImageView.setImage(FXAvatar.load(item.getAvatar()));
            nicknameLabel.setText(item.getNickname());
            messageLabel.setText(item.getMessage());
        }
        timestampLabel.setText(new SimpleDateFormat("yy/MM/dd").format(new Date(item.getTimestamp())));
        messageCountLabel.setText(item.getMessageCount() > 99 ? "99+" : String.valueOf(item.getMessageCount()));
        messageCountLabel.setLayoutX(item.getMessageCount() > 0 ? 35 : -35);

        setGraphic(chatRowHBox);
    }
}

样式美化

聊天列表使用的是JavaFX的ListView控件,默认情况下,这个控件不是很美观,所以需要对其进行样式美化,完整的css如下:

* {
  -fx-font-family: "微软雅黑", "sans-serif";
  -fx-font-size: 14px;
  -fx-border-radius: 0;
  -fx-background-radius: 0;
}

.list-view {
  -fx-background-color: transparent;
}

.list-cell {
  -fx-background-color: #f4f4f4;
  -fx-text-fill: black;
}

.list-cell:empty {
  visibility: hidden;
}

.list-cell:hover {
  -fx-background-color: derive(#c8c8c8, 50%);
}

.list-cell:filled:selected:focused {
  -fx-background-color: #c8c8c8;
  -fx-text-fill: black;
}

.split-pane > .split-pane-divider {
  -fx-background-color: transparent;
}

.menu-button > .arrow-button {
  -fx-padding: 0;
}

.menu-button > .arrow-button > .arrow {
  -fx-padding: 0;
}

.track {
  -fx-background-color: transparent;
}

.thumb {
  -fx-pref-width: 10px;
  -fx-background-color: derive(#969696, 50%);
  -fx-background-radius: 0em;
}

.increment-arrow,
.decrement-arrow {
  -fx-padding: 0;
}

.increment-button,
.decrement-button {
  -fx-padding: 0 0 0 0;
}

.scroll-bar {
  -fx-opacity: 0;
}

:hover .scroll-bar {
  -fx-opacity: 1;
}

.list-view .scroll-bar,
.text-area .scroll-bar {
  -fx-background-color: transparent;
}

.list-view .decrement-button {
  -fx-padding: 0 10 0 0;
}

事件处理

重新实现第四篇【主界面】中的切换列表事件:

public void onChatClick(ActionEvent actionEvent) {
    listVBox.getChildren().clear();
    listVBox.getChildren().add(FXComponent.chatListController());
    chatButton.setDisable(true);
    contactsButton.setDisable(false);
}

缓存控件逻辑:

public static Parent chatListController() {
    return cache.computeIfAbsent("chatListController", k -> FX.fxml(ChatListController.class));
}

标签:05,fx,列表,item,聊天,background,仿微信,public,color
From: https://www.cnblogs.com/michong2022/p/17557755.html

相关文章

  • 仿微信聊天程序 - 07. 好友信息
    本文是仿微信聊天程序专栏的第七篇文章,主要记录了【好友信息】的界面实现。界面设计这里的好友信息界面没有处理复杂的功能,仅仅显示好友信息,支持在此界面中发起聊天而已,总体的界面设计如下图所示:界面布局好友信息仅仅只是信息展示,布局相对比较简单,这里采用VBox和HBox组合使用......
  • 仿微信聊天程序 - 06. 好友列表
    本文是仿微信聊天程序专栏的第六篇文章,主要记录了【好友列表】的界面实现。界面设计好友列表在主界面左边,界面UI风格跟聊天列表类似,只不过相比聊天列表更加简单,不需要显示聊天信息,时间等,总体界面设计如下:界面布局跟好友列表一样,聊天列表的布局也分为两部,列表布局和列表中的每......
  • 仿微信聊天程序 - 08. 聊天窗口
    本文是仿微信聊天程序专栏的第八篇文章,主要记录了【聊天窗口】的界面实现。界面设计聊天窗口是整个聊天程序的核心控件,比较复杂,大致可以分为上中下三个部分,上面显示用户昵称以及一些操作菜单,中间是聊天内容显示区域,下面的信息发送的区域,总体界面设计如下:界面布局根据界面设计......
  • 8051单片机实现呼吸灯
    电路连接:灯由P2口控制,引脚输出高电平则熄灭,输出低电平则点亮;MCU时钟6兆赫兹。占空比从0%,10%,20%,……到100%共11级。定时器设置为固定间隔,例如一毫秒触发一次中断,那么输出一个占空比40%的10毫秒方波的逻辑可以是:Timer0_ISR:1、重装计数器;2、计数值加一,若大于等于10说明一个周......
  • 105.C++初始化
    105.C++初始化C++中变量的初始化有很多种方式,如:默认初始化,值初始化,直接初始化,拷贝初始化,列表初始化。1.默认初始化默认初始化是指定义变量时没有指定初值时进行的初始化操作。默认初始化变量的值与变量的类型与变量定义的位置有关系:1.1内置类型变量对于内置类型变量(如in......
  • 105.什么是SamesiteCookie属性
    105.什么是SamesiteCookie属性?SamesiteCookie表示同站cookie,避免cookie被第三方所利用。将Samesite设为strict,这种称为严格模式,表示这个cookie在任何情况下都不可能作为第三方cookie。将Samesite设为Lax,这种模式称为宽松模式,如果这个请求是个GET请求,并......
  • 05-优化程序性能
    写程序最主要的目标就是使它在所有可能的情况下都正确工作。一个运行得很快但是给出错误结果的程序没有任何用处。程序员必须写出清晰简洁的代码,这样做不仅是为了自己能够看懂代码,也是为了在检査代码和今后需要修改代码时,其他人能够读懂和理解代码。另一方面,在很多情况下,让程序运......
  • C语言-05
    预处理/*---用#号开头的命令是预处理命令---“预处理”即:预先处理,在编译前对代码进行一个预先处理include<文件.h>//这个是文件包含命令总上所述,#include<stdio.h>即是:执行“预处理文件包含stdio.h”*/# include/*当main......
  • 基于GPT搭建私有知识库聊天机器人(五)函数调用
    文章链接:基于GPT搭建私有知识库聊天机器人(一)实现原理基于GPT搭建私有知识库聊天机器人(二)环境安装基于GPT搭建私有知识库聊天机器人(三)向量数据训练基于GPT搭建私有知识库聊天机器人(四)问答实现OpenAI在6月13日发布了几个重磅更新,其中包括:开放了16k上下文的GPT-3.5-Turbo模型......
  • Vue聊天界面请求AzureOpenAI
    Vue工程目录: <scriptsetup>import{ref}from"vue";importaxiosfrom"axios";importMarkdownItfrom"markdown-it";importhljsfrom"highlight.js";constlist=ref([]);constquestion=ref(""......