本文是仿微信聊天程序专栏的第六篇文章,主要记录了【好友列表】的界面实现。
界面设计
好友列表在主界面左边,界面UI风格跟聊天列表类似,只不过相比聊天列表更加简单,不需要显示聊天信息,时间等,总体界面设计如下:
界面布局
跟好友列表一样,聊天列表的布局也分为两部,列表布局和列表中的每一行的布局,其中列表布局的完整fxml如下:
<HBox prefHeight="640.0" prefWidth="250.0" xmlns:fx="http://javafx.com/fxml" stylesheets="@ContactsListController.css" fx:controller="michong.javafx.wx.view.contacts.ContactsListController"> <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="contactsListView" VBox.vgrow="ALWAYS"/> </children> </VBox> </children> </HBox>
列表项的布局完整fxml如下:
<HBox stylesheets="@ContactsRowController.css" alignment="CENTER" prefHeight="60.0" prefWidth="235.0" spacing="5.0" fx:id="contactsRowHBox" xmlns:fx="http://javafx.com/fxml/"> <children> <ImageView fx:id="avatarImageView" fitHeight="40.0" fitWidth="40.0"/> <VBox alignment="CENTER_LEFT" prefWidth="160.0" spacing="4.0" HBox.hgrow="ALWAYS"> <children> <Label fx:id="nicknameLabel" styleClass="name-label"/> </children> <padding> <Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/> </padding> </VBox> </children> <padding> <Insets left="5.0"/> </padding> </HBox>
构建控件
从上面的界面布局中可以看到列表项并没有直接关联Controller,因为这里我实现动态构建,所以在初始化的时候绑定Controller,具体实现如下:
/** * @author michong */ public class ContactsRowController extends ListCell<ContactsVO> { public HBox contactsRowHBox; public ImageView avatarImageView; public Label nicknameLabel; private FXMLLoader loader; @Override protected void updateItem(ContactsVO item, boolean empty) { super.updateItem(item, empty); setText(null); if (empty || item == null) { setGraphic(null); return; } if (loader == null) { loader = new FXMLLoader(getClass().getResource("/" + getClass().getName().replace(".", "/") + ".fxml")); loader.setController(this); try { loader.load(); } catch (IOException e) { throw new RuntimeException(e); } } avatarImageView.setImage(FXAvatar.load(item.getAvatar())); nicknameLabel.setText(item.getNickname()); setGraphic(contactsRowHBox); } }
样式美化
好友列表使用的是JavaFX的ListView控件,默认情况下,这个控件不是很美观,所以需要对其进行样式美化,这里的css跟好友列表的css是完全一样的,因为都是针对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 onContactsClick(ActionEvent actionEvent) { listVBox.getChildren().clear(); listVBox.getChildren().add(FXComponent.contactsListController()); contactsButton.setDisable(true); chatButton.setDisable(false); }
缓存控件逻辑:
public static Parent contactsListController() { return cache.computeIfAbsent("contactsListController", k -> FX.fxml(ContactsListController.class)); }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库