Skip to content

[Indexes 索引] 列表数据1000条页面卡顿 #687

Description

@jhyjhy-cn

tdesign-flutter 版本

tdesign_flutter: ^0.2.2

重现链接

No response

重现步骤/代码

数据量过多会导致页面卡顿
`import 'package:im_flutter/app/core/index.dart';
import 'package:im_flutter/app/data/models/vo/friend_vo.dart';
import 'package:im_flutter/app/stores/friend_store.dart';
import 'package:lpinyin/lpinyin.dart';

class FriendController extends GetxController with BaseControllerMixin {
@OverRide
String get builderId => 'FriendController';
final RxBool isLoading = true.obs;
final FriendStore friendStore = Get.find();

final RxList friendList = [].obs;
final RxList<Map<String, dynamic>> friendedList =
<Map<String, dynamic>>[].obs;

Future _loadFriends() async {
try {
isLoading.value = true;
if (friendStore.friends.isNotEmpty) {
// 获取所有好友列表
friendList.assignAll(friendStore.friends);
// 按首字母分组
_groupByFirstLetter();
isLoading.value = false;
return;
}

  // 如果数据库也没有,尝试重新加载
  await friendStore.loadFriend();
  // 获取所有好友列表
  friendList.assignAll(friendStore.friends);
  // 按首字母分组
  _groupByFirstLetter();

  isLoading.value = false;
} catch (e) {
  isLoading.value = false;
  AppLogger.error('加载群组列表失败: $e');
}

}

/// 按首字母分组
void _groupByFirstLetter() {
final Map<String, List> groups = {};

for (final item in friendList) {
  if (item.nickName.isEmpty) continue;

  // 获取首字母
  final pinyin = PinyinHelper.getPinyinE(item.nickName!);
  final firstLetter = pinyin.isNotEmpty ? pinyin[0].toUpperCase() : '#';

  if (!groups.containsKey(firstLetter)) {
    groups[firstLetter] = [];
  }
  groups[firstLetter]!.add(item);
}

// 排序并转换为列表
final sortedKeys = groups.keys.toList()..sort();
friendedList.assignAll(
  sortedKeys
      .map((key) => {
            'index': key,
            'children': groups[key]!,
          })
      .toList(),
);

}

@OverRide
void onInit() {
super.onInit();
_loadFriends();
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:im_flutter/app/common/widgets/sized_box_x/index.dart';
import 'package:im_flutter/app/core/localization/localization_service.dart';
import 'package:im_flutter/app/core/utils/screen_util.dart';
import 'package:im_flutter/app/core/widgets/keep_alive_wrapper.dart';
import 'package:im_flutter/app/data/models/vo/friend_vo.dart';
import 'package:im_flutter/app/pages/friend/friend_controller.dart';
import 'package:im_flutter/app/common/widgets/app_bars/custom_app_bar.dart';
import 'package:im_flutter/app/pages/home/home_controller.dart';
import 'package:im_flutter/app/routes/app_pages.dart';
import 'package:im_flutter/generated/locales.g.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';
import 'package:window_manager/window_manager.dart';

class FriendView extends GetView {
const FriendView({super.key});

@OverRide
Widget build(BuildContext context) {
return KeepAliveWrapper(
child: Scaffold(
appBar: _wapAppBar(context),
body: Obx(() {
final isLoading = controller.isLoading.value;
if (isLoading) return _buildSkeleton(context);
return Column(
children: [

          Expanded(
            child: _buildSimple(context),
          ),
        ],
      );
    }),
  ),
);

}

Widget _buildSimple(BuildContext context) {
return Obx(() {
final indexList = controller.friendedList
.map((item) => item['index'] as String)
.toList();
return Container(
color: Colors.white,
child: TDIndexes(
indexList: indexList,
builderContent: (context, index) {
final item = controller.friendedList.firstWhere(
(element) => element['index'] == index,
orElse: () => {'children': []},
);
final list = item['children'] as List;
return ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: list.length,
itemBuilder: (context, index) {
final friend = list[index];
return TDCell(
title: friend.nickName,
onClick: (cell) {
Get.toNamed('${Routes.userInfo}?id=${friend.id}');
},
);
},
);
},
),
);
});
}

AppBar _wapAppBar(BuildContext context) {
return CustomAppBar(
title: LocalizationService.get(LocaleKeys.friend_title),
showBackButton: false,
);
}

Widget _buildSkeleton(BuildContext context) {
return Container(
width: double.infinity,
height: double.infinity,
padding: ScreenUtil.padding(all: 16),
color: Colors.red,
child: Column(
children: List.generate(10, (index) {
return Padding(
padding: ScreenUtil.padding(bottom: 16),
child: Text('loading'),
);
})),
);
}
}
`

期望结果

No response

实际结果

No response

Flutter版本

tdesign_flutter: ^0.2.2

设备与机型信息

Android

系统版本

Android 12

补充说明

数据量过多会导致页面卡顿
我测试的数据有1000条

IssueShoot

预估时长:3
期望完成时间:2025-8-7
开发难度:中
参与人数:1
需求对接人:jackjflin
验收标准:实现期望改造效果,提 MR并通过 验收无误
备注:最终激励以实际提交 pr 并合并为准。TDesignFlutter贡献指南:https://tdesign.tencent.com/flutter/develop

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions