功能介紹:
仿微信聊天對話對話信息列表,顯示發送文本和接收文本,參考文檔創建列表。
知識點:
- 熟悉對List控件的使用。
- 熟悉對Text控制定義,如修改邊框等。
- 手動控制列表的跳轉。
- 動態添加列表數據。
- 使用構造函數初始化數據。
使用環境:
- API 9
- DevEco Studio 4.0 Release
- Windows 11
- Stage模型
- ArkTS語言
所需權限:
- 無需權限
效果圖:

在src/main/ets/model/Msg.ets中,定義消息的結構:
// 消息類型,分別是發送和接收
export const TYPE_RECEIVED = 0;
export const TYPE_SENT = 1;
export class Msg {
content: string;
type: number;
constructor(content: string, type: number) {
this.content = content;
this.type = type;
}
}
src/main/ets/model/MsgDataSource.ets編寫的是對列表的操作,如添加數據、獲取列表大小,通過操作這個對象,控制列表顯示。
import { Msg } from './Msg';
export class MsgDataSource implements IDataSource {
private listeners: DataChangeListener[] = [];
private listData = new Array<Msg>();
constructor() {
this.addData(new Msg('你好,你叫什麼名字', 0))
this.addData(new Msg('主人你好,我是你的AI助手', 1))
this.addData(new Msg('今天天氣怎麼樣', 0))
this.addData(new Msg('今天天氣晴朗', 1))
}
public totalCount(): number {
return this.listData.length;
}
public getData(index: number): Msg {
return this.listData[index];
}
public addData(msg: Msg): void {
// this.listData.push()
this.listData = this.listData.concat(msg);
this.notifyDataAdd(this.listData.length - 1);
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const position = this.listeners.indexOf(listener);
if (position >= 0) {
this.listeners.splice(position, 1);
}
}
notifyDataAdd(index: number): void {
this.listeners.forEach((listener: DataChangeListener) => {
listener.onDataAdd(index);
})
}
notifyDataChange(index: number): void {
this.listeners.forEach((listener: DataChangeListener) => {
listener.onDataChange(index);
})
}
}
頁面代碼:
import { Msg, TYPE_SENT } from '../model/Msg';
import { MsgDataSource } from '../model/MsgDataSource';
@Entry
@Component
struct Index {
@Provide msgListData: MsgDataSource = new MsgDataSource();
private listScroller: Scroller = new Scroller();
build() {
Column() {
Scroll() {
Column() {
Row() {
List({ space: 16, scroller: this.listScroller }) {
LazyForEach(this.msgListData, (item: Msg) => {
ListItem() {
Column() {
if (item?.type == TYPE_SENT) {
Column() {
Text(item?.content)
.border({ width: 1, color: Color.Black, radius: 10 })
.padding(10)
.backgroundColor(Color.Yellow)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
} else {
Column() {
Text(item?.content)
.border({ width: 1, color: Color.Black, radius: 10 })
.padding(10)
.backgroundColor(Color.Pink)
}
.width('100%')
.alignItems(HorizontalAlign.End)
}
}
.width('100%')
}
})
}
.width('95%')
.height('100%')
}
.justifyContent(FlexAlign.Center)
.alignItems(VerticalAlign.Top)
.padding({ top: 10, bottom: 10 })
.width('100%')
.height('100%')
}
.width('100%')
}
.scrollBar(BarState.Off)
.width('100%')
.height('90%')
Row() {
Button('添加數據')
.width('100%')
.margin({ bottom: 10 })
.onClick(() => {
let myDate: Date = new Date()
let content = `現在是:${myDate.getHours()}時${myDate.getMinutes()}分${myDate.getSeconds()}秒`
this.msgListData.addData(new Msg('現在幾點了?', 0))
this.msgListData.addData(new Msg(content, 1))
this.listScroller.scrollToIndex(this.msgListData.totalCount() - 1)
})
}
.height('10%')
.width('100%')
.alignItems(VerticalAlign.Bottom)
}
.width('100%')
.height('100%')
}
}