通讯录完成
BIN
assets/chats/chat_bubble_img_broken.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
assets/chats/default_avatar.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/chats/delete_emoji.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
assets/chats/file_msg.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
assets/chats/index_bar.png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
BIN
assets/chats/play_voice_receive.gif
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/chats/play_voice_send.gif
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
assets/chats/voice_volume_1.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/chats/voice_volume_2.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
assets/chats/voice_volume_3.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
assets/chats/voice_volume_4.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
assets/chats/voice_volume_5.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/chats/voice_volume_6.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
assets/chats/voice_volume_7.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
@@ -1,4 +1,5 @@
|
|||||||
import 'package:azlistview/azlistview.dart';
|
import 'package:azlistview/azlistview.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
|
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
|
||||||
|
|
||||||
class ContactInfoModel extends ISuspensionBean {
|
class ContactInfoModel extends ISuspensionBean {
|
||||||
@@ -7,6 +8,8 @@ class ContactInfoModel extends ISuspensionBean {
|
|||||||
String? tagIndex;
|
String? tagIndex;
|
||||||
String? namePinyin;
|
String? namePinyin;
|
||||||
V2TimFriendInfo? friendInfo;
|
V2TimFriendInfo? friendInfo;
|
||||||
|
IconData? icon;
|
||||||
|
Color? color;
|
||||||
|
|
||||||
ContactInfoModel({
|
ContactInfoModel({
|
||||||
required this.name,
|
required this.name,
|
||||||
@@ -14,6 +17,8 @@ class ContactInfoModel extends ISuspensionBean {
|
|||||||
this.tagIndex,
|
this.tagIndex,
|
||||||
this.namePinyin,
|
this.namePinyin,
|
||||||
this.friendInfo,
|
this.friendInfo,
|
||||||
|
this.icon,
|
||||||
|
this.color,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:chat/services/tim_service.dart';
|
|||||||
import 'package:chat/utils/im_tools.dart';
|
import 'package:chat/utils/im_tools.dart';
|
||||||
import 'package:chat/utils/network/http.dart';
|
import 'package:chat/utils/network/http.dart';
|
||||||
import 'package:chat/utils/ui_tools.dart';
|
import 'package:chat/utils/ui_tools.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:lpinyin/lpinyin.dart';
|
import 'package:lpinyin/lpinyin.dart';
|
||||||
import 'package:tencent_im_sdk_plugin/enum/friend_type_enum.dart';
|
import 'package:tencent_im_sdk_plugin/enum/friend_type_enum.dart';
|
||||||
@@ -27,6 +28,30 @@ class TimFriendService extends GetxService {
|
|||||||
/// 格式化后的联系人信息
|
/// 格式化后的联系人信息
|
||||||
var contacts = List<ContactInfoModel>.empty(growable: true).obs;
|
var contacts = List<ContactInfoModel>.empty(growable: true).obs;
|
||||||
|
|
||||||
|
final List<ContactInfoModel> _topList = [
|
||||||
|
ContactInfoModel(
|
||||||
|
name: '新的朋友',
|
||||||
|
userID: '',
|
||||||
|
tagIndex: '@',
|
||||||
|
icon: Icons.person_add_alt,
|
||||||
|
color: Colors.amber,
|
||||||
|
),
|
||||||
|
ContactInfoModel(
|
||||||
|
name: '群聊',
|
||||||
|
userID: '',
|
||||||
|
tagIndex: '@',
|
||||||
|
icon: Icons.group,
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
|
ContactInfoModel(
|
||||||
|
name: '订阅消息',
|
||||||
|
userID: '',
|
||||||
|
tagIndex: '@',
|
||||||
|
icon: Icons.mark_email_read,
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
Future<void> fetchList() async {
|
Future<void> fetchList() async {
|
||||||
var result = await friendshipManager.getFriendList();
|
var result = await friendshipManager.getFriendList();
|
||||||
if (result.code == 0) {
|
if (result.code == 0) {
|
||||||
@@ -52,6 +77,7 @@ class TimFriendService extends GetxService {
|
|||||||
|
|
||||||
SuspensionUtil.sortListBySuspensionTag(contacts);
|
SuspensionUtil.sortListBySuspensionTag(contacts);
|
||||||
SuspensionUtil.setShowSuspensionStatus(contacts);
|
SuspensionUtil.setShowSuspensionStatus(contacts);
|
||||||
|
contacts.insertAll(0, _topList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ class ImTools {
|
|||||||
static Widget susItem(
|
static Widget susItem(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
String tag, {
|
String tag, {
|
||||||
double susHeight = 40,
|
double susHeight = 32,
|
||||||
}) {
|
}) {
|
||||||
return Container(
|
return Container(
|
||||||
height: susHeight,
|
height: susHeight,
|
||||||
@@ -201,6 +201,10 @@ class ImTools {
|
|||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
tag,
|
tag,
|
||||||
|
style: const TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: AppColors.unactive,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,26 +25,53 @@ class _ContactPageState extends State<ContactPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return GetX<TimFriendService>(
|
return Scaffold(
|
||||||
builder: (_) {
|
appBar: AppBar(
|
||||||
return Scaffold(
|
title: const Text('通讯录'),
|
||||||
appBar: AppBar(
|
actions: [
|
||||||
title: Text('我的好友(${_.friends.length})'),
|
IconButton(
|
||||||
actions: [
|
onPressed: () {
|
||||||
IconButton(
|
// Get.toNamed(ImRoutes.friendSearch);
|
||||||
onPressed: () {
|
},
|
||||||
// Get.toNamed(ImRoutes.friendSearch);
|
icon: const Icon(Icons.search_outlined),
|
||||||
},
|
|
||||||
icon: const Icon(Icons.search_outlined),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
body: AzListView(
|
],
|
||||||
physics: const ClampingScrollPhysics(),
|
),
|
||||||
data: _.contacts,
|
body: GetX<TimFriendService>(builder: (_) {
|
||||||
itemCount: _.contacts.length,
|
return AzListView(
|
||||||
itemBuilder: (__, index) {
|
physics: const BouncingScrollPhysics(),
|
||||||
ContactInfoModel info = _.contacts[index];
|
data: _.contacts,
|
||||||
|
itemCount: _.contacts.length,
|
||||||
|
itemBuilder: (__, index) {
|
||||||
|
ContactInfoModel info = _.contacts[index];
|
||||||
|
if (info.tagIndex == '@') {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
ListTile(
|
||||||
|
onTap: () async {},
|
||||||
|
leading: Container(
|
||||||
|
width: 40,
|
||||||
|
height: 40,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: info.color!,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
info.icon,
|
||||||
|
size: 26,
|
||||||
|
color: AppColors.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
tileColor: AppColors.white,
|
||||||
|
title: Text(info.name),
|
||||||
|
),
|
||||||
|
const Divider(
|
||||||
|
height: 0,
|
||||||
|
indent: 72,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
@@ -69,19 +96,22 @@ class _ContactPageState extends State<ContactPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
susItemBuilder: (__, index) {
|
},
|
||||||
ContactInfoModel model = _.contacts[index];
|
susItemBuilder: (__, index) {
|
||||||
if ('↑' == model.getSuspensionTag()) {
|
ContactInfoModel model = _.contacts[index];
|
||||||
return Container();
|
if ('@' == model.getSuspensionTag()) {
|
||||||
}
|
return Container();
|
||||||
return ImTools.susItem(context, model.getSuspensionTag());
|
}
|
||||||
},
|
return ImTools.susItem(
|
||||||
indexBarData: SuspensionUtil.getTagIndexList(_.contacts).toList(),
|
context,
|
||||||
indexBarOptions: ImTools.indexBarOptions,
|
model.getSuspensionTag(),
|
||||||
),
|
);
|
||||||
|
},
|
||||||
|
indexBarData: SuspensionUtil.getTagIndexList(_.contacts).toList(),
|
||||||
|
indexBarOptions: ImTools.indexBarOptions,
|
||||||
);
|
);
|
||||||
},
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ dev_dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
assets:
|
assets:
|
||||||
|
- assets/chats/
|
||||||
- assets/icons/
|
- assets/icons/
|
||||||
- assets/images/
|
- assets/images/
|
||||||
- assets/images/empty/
|
- assets/images/empty/
|
||||||
|
|||||||