chat_index_bar 1.0.1 chat_index_bar: ^1.0.1 copied to clipboard
A chat_index_bar is a package of search controls floating on the chat interface, which can expand the index list to facilitate quick search of chat records.
import 'package:chat_index_bar/chat_index_bar.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
final Color WeChatThemeColor = Color.fromRGBO(220, 220, 220, 1.0);
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'use cases for chat index bar.',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.standard,
),
home: const FriendsPage(),
);
}
}
class FriendsPage extends StatefulWidget {
const FriendsPage({Key? key}) : super(key: key);
@override
_FriendsPageState createState() => _FriendsPageState();
}
class _FriendsPageState extends State<FriendsPage> {
// 字典里存放item和高度的对应数据
final Map _groupOffsetMap = {
indexWords[0]: 0.0,
indexWords[0]: 0.0,
};
final ScrollController _scrollController = ScrollController();
final List<Friends> _listDatas = [];
@override
void initState() {
super.initState();
// 方法一
// _listDatas.addAll(datas);
// _listDatas.addAll(datas);
// 方法二 step1 链式 添加【增量数据】
_listDatas
// ..addAll(datas)
// ..addAll(datas)
..addAll(datas);
// step2 排序
_listDatas.sort((Friends a, Friends b) {
return a.indexLetter.compareTo(b.indexLetter);
});
var _groupOffset = 54.5 * 4;
// 经过循环计算,将每一个头的位置算出来,放入字典。
for (int i = 0; i < _listDatas.length; i++) {
if (i < 1) {
// 第一个Cell
_groupOffsetMap.addAll({_listDatas[i].indexLetter: _groupOffset});
// 保存完了再加_groupOffset偏移
_groupOffset += 84.5;
} else if (_listDatas[i].indexLetter == _listDatas[i - 1].indexLetter) {
// 没有头部,只需要加偏移量
_groupOffset += 54.5;
} else {
// 这部分是有头部的Cell
_groupOffsetMap.addAll({_listDatas[i].indexLetter: _groupOffset});
_groupOffset += 84.5;
}
}
}
final List _headerData = [
Friends(imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/9/99/Sample_User_Icon.png', name: '新的朋友'),
Friends(imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/9/99/Sample_User_Icon.png', name: '群聊'),
Friends(imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/9/99/Sample_User_Icon.png', name: '标签'),
Friends(imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/9/99/Sample_User_Icon.png', name: '公众号'),
];
Widget _itemForRow(BuildContext context, int index) {
// 显示头部 系统图标的cell
if (index < _headerData.length) {
// print(index);
return _FriendCell(
imageUrl: _headerData[index].imageUrl,
name: _headerData[index].name,
);
// return _FriendHeaderCell(
// imageAssets: _headerData[index].imageUrl,
// name: _headerData[index].name,
// );
}
// 显示剩下的cell
// 如果当前和上一个cell的IndexLetter一样, 就不显示
bool _hideIndexLetter = (index - 4 > 0 &&
(_listDatas[index - 4].indexLetter ==
_listDatas[index - 5].indexLetter));
return _FriendCell(
imageUrl: _listDatas[index - 4].imageUrl,
name: _listDatas[index - 4].name,
groupTitle: _hideIndexLetter ? "" : _listDatas[index - 4].indexLetter,
);
/*if (index - 4 > 0 &&
(_listDatas[index - 4].indexLetter ==
_listDatas[index - 5].indexLetter)) {
return _FriendCell(
imageUrl: _listDatas[index - 4].imageUrl,
name: _listDatas[index - 4].name,
);
}
// 剩下的显示
return _FriendCell(
imageUrl: _listDatas[index - 4].imageUrl,
name: _listDatas[index - 4].name,
groupTitle: _listDatas[index - 4].indexLetter,
); */
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: WeChatThemeColor,
title: const Text('通讯录'),
actions: <Widget>[
GestureDetector(
child: Container(
margin: const EdgeInsets.only(right: 10),
child: const Image(
image: AssetImage('images/icon_friends_add.png'),
width: 25,
),
),
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) => DiscoverChildPage(
// title: '添加好友',
// )));
},
)
],
),
body: Stack(
children: <Widget>[
ListView.builder(
controller: _scrollController,
itemCount: _listDatas.length + _headerData.length,
itemBuilder: _itemForRow,
), // 列表
IndexBar(
indexBarCallBack: (String str) {
if (kDebugMode) {
print('我收到了$str');
}
if (_groupOffsetMap[str] != null) {
_scrollController.animateTo(_groupOffsetMap[str],
duration: const Duration(microseconds: 1),
curve: Curves.easeIn);
}
},
bubbleImage: const Image(
///< 后期转进来,本地使用
image: AssetImage('images/气泡.png', package: 'chat_index_bar'),
width: 60,
),
), // 悬浮检索控件
],
),
);
}
}
class _FriendCell extends StatelessWidget {
final String imageUrl;
final String name;
final String groupTitle;
final String imageAssets;
const _FriendCell(
{this.imageUrl = '',
this.name = '',
this.groupTitle = '',
this.imageAssets = ''});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(left: 10),
height: groupTitle != "" ? 30 : 0,
color: const Color.fromRGBO(1, 1, 1, 0.0),
child: groupTitle != ""
? Text(
groupTitle,
style: const TextStyle(color: Colors.grey),
)
: null,
), // Cell的头
Container(
color: Colors.white,
child: Row(
children: <Widget>[
Container(
margin: const EdgeInsets.all(10),
width: 34,
height: 34,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
image: DecorationImage(
image: imageUrl != ""
? NetworkImage(imageUrl)
: AssetImage(imageAssets) as ImageProvider,
)),
), // 图片
Text(
name,
style: const TextStyle(fontSize: 17),
), // 昵称
],
),
), // Cell的内容
Container(
height: 0.5,
color: WeChatThemeColor,
child: Row(
children: <Widget>[
Container(
width: 50,
color: Colors.white,
),
],
),
), // 分割线
],
);
}
}
class _FriendHeaderCell extends StatelessWidget {
final String name;
final String imageAssets;
const _FriendHeaderCell({this.name = '', this.imageAssets = ''});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Row(
children: <Widget>[
Container(
margin: const EdgeInsets.all(10),
width: 34,
height: 34,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6.0),
image: DecorationImage(
image: AssetImage(imageAssets),
)),
), // 图片
Text(
name,
style: const TextStyle(fontSize: 17),
), // 昵称
],
),
);
}
}
class Friends {
final String imageUrl;
final String name;
final String indexLetter;
Friends({this.imageUrl = '', this.name = '', this.indexLetter = ''});
}
List<Friends> datas = [
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/22.jpg",
name: "Lina",
indexLetter: "L"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/17.jpg",
name: "菲儿",
indexLetter: "F"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "安莉",
indexLetter: "A"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "Eam",
indexLetter: "E"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "安莉",
indexLetter: "A"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "阿贵",
indexLetter: "A"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/22.jpg",
name: "贝拉",
indexLetter: "B"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/27.jpg",
name: "Abby",
indexLetter: "A"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "COCO",
indexLetter: "C"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/17.jpg",
name: "wkk",
indexLetter: "W"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "凯蒂",
indexLetter: "K"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "盖茨",
indexLetter: "G"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/22.jpg",
name: "Hank",
indexLetter: "H"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "Yuki",
indexLetter: "Y"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/27.jpg",
name: "张萌",
indexLetter: "Z"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/22.jpg",
name: "COCO",
indexLetter: "C"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/17.jpg",
name: "赛琳娜",
indexLetter: "S"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "Wangle",
indexLetter: "W"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "西涅",
indexLetter: "X"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/22.jpg",
name: "Right",
indexLetter: "R"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "Vivina",
indexLetter: "V"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/27.jpg",
name: "秦小君",
indexLetter: "Q"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "Peter",
indexLetter: "P"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/17.jpg",
name: "欧拉琳",
indexLetter: "O"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/22.jpg",
name: "Python",
indexLetter: "P"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "C++",
indexLetter: "C"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "Java",
indexLetter: "J"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/16.jpg",
name: "Betty",
indexLetter: "B"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/17.jpg",
name: "Objective-C",
indexLetter: "O"),
Friends(
imageUrl: "https://randomuser.me/api/portraits/women/31.jpg",
name: "Swift",
indexLetter: "S"),
Friends(
imageUrl: 'https://randomuser.me/api/portraits/women/16.jpg',
name: 'web',
indexLetter: 'W'),
Friends(
imageUrl: 'https://randomuser.me/api/portraits/women/17.jpg',
name: 'PHP',
indexLetter: 'P'),
];