1.国家区号列表(带字母索引侧边栏)
import 'package:generated/l10n.dart';
import 'package:widget/login/area_index_bar_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class LoginAreaListWidget extends StatefulWidget {
State<StatefulWidget> createState() => _LoginAreaListWidgetState();
}
class _LoginAreaListWidgetState extends State<LoginAreaListWidget> {
// 字典里面放item和高度对应的数据
final Map _groupOffsetMap = {};
ScrollController _scrollController;
final List<Areas> _listDatas = [];
void initState() {
super.initState();
_listDatas.addAll(datas);
var _groupOffset = 80.h * (_headerData.length - 1) + 40.h;
//经过循环计算,将每一个头的位置算出来,放入字典
for (int i = 0; i < _listDatas.length; i++) {
if (_listDatas[i].name == null) {
_groupOffsetMap.addAll({_listDatas[i].indexLetter: _groupOffset});
_groupOffset += 40.h;
} else {
_groupOffset += 80.h;
}
}
_scrollController = ScrollController();
}
final List<Areas> _headerData = [
Areas(),
Areas(areaCode: 86, name: S.current.c1),
Areas(areaCode: 852, name: S.current.c2),
Areas(areaCode: 1, name: S.current.c3),
Areas(areaCode: 44, name: S.current.c4),
Areas(areaCode: 1, name: S.current.c5),
Areas(areaCode: 61, name: S.current.c6),
Areas(areaCode: 49, name: S.current.c7),
Areas(areaCode: 81, name: S.current.c8),
];
Widget _itemForRow(BuildContext context, int index) {
// 系统cell
if (index < _headerData.length) {
if (index == 0) {
return _FriendsCell(
name: S.current.remen,
groupTitle: S.current.remen,
);
}
return _FriendsCell(
areaCode: _headerData[index].areaCode,
name: _headerData[index].name,
hideBorder: index == _headerData.length - 1 ? true : false,
);
}
int length = _headerData.length;
//显示剩下的cell
//如果当前和上一个cell的indexLetter一样,就不显示
bool _hideIndexLetter = (index - length > 0 &&
_listDatas[index - length].indexLetter ==
_listDatas[index - (length + 1)].indexLetter);
// 如果当前和下一个cell的indexLetter不一样,就不显示border
bool _hideBorder = index + 1 == _listDatas.length + _headerData.length
? true
: (index - length > 0 &&
_listDatas[index - length].indexLetter !=
_listDatas[index - (length - 1)].indexLetter);
return _FriendsCell(
areaCode: _listDatas[index - length].areaCode,
name: _listDatas[index - length].name,
groupTitle:
_hideIndexLetter ? null : _listDatas[index - length].indexLetter,
hideBorder: _hideBorder);
}
Widget build(BuildContext context) {
return Stack(
children: [
Container(
child: ListView.builder(
itemBuilder: _itemForRow,
controller: _scrollController,
itemCount: _listDatas.length + _headerData.length,
),
),
Positioned(
top: 0,
right: 0,
bottom: 0,
child: Container(
width: 100.w,
child: AreaIndexBarWidget(
indexBarCallBack: (String str) {
if (_groupOffsetMap[str] != null) {
_scrollController.animateTo(_groupOffsetMap[str],
duration: Duration(milliseconds: 10),
curve: Curves.easeIn);
}
},
),
))
],
);
}
}
class _FriendsCell extends StatelessWidget {
final int areaCode;
final String name;
final String groupTitle;
final bool hideBorder;
const _FriendsCell(
{this.areaCode, this.name, this.groupTitle, this.hideBorder}); //首字母大写
Widget build(BuildContext context) {
return groupTitle != null
? Container(
color: Colors.black.withOpacity(0.1),
padding: EdgeInsets.only(left: 40.w),
height: 40.h,
alignment: Alignment.centerLeft,
child: Text(
groupTitle,
style: TextStyle(fontSize: 24.sp, color: Color(0xff333333)),
),
)
: InkWell(
onTap: () {
Navigator.pop(context, areaCode);
},
child: Container(
color: Colors.white,
height: 80.h,
padding: EdgeInsets.only(left: 40.w, right: 100.w),
child: Container(
decoration: BoxDecoration(
border: hideBorder
? Border()
: Border(
bottom: BorderSide(
width: 1,
color: Color(0xff5dc8b6).withOpacity(0.3)))),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
name,
style:
TextStyle(fontSize: 28.sp, color: Color(0xff333333)),
),
Text(
'+$areaCode',
style:
TextStyle(fontSize: 28.sp, color: Color(0xff333333)),
)
],
),
),
),
);
}
}
class Areas {
final int areaCode;
final String name;
final String indexLetter; //首字母大写
Areas({this.areaCode, this.name, this.indexLetter});
}
List<Areas> datas = [
Areas(indexLetter: 'A'),
Areas(areaCode: 43, name: S.current.c9, indexLetter: 'A'),
Areas(areaCode: 61, name: S.current.c10, indexLetter: 'A'),
Areas(areaCode: 20, name: S.current.c11, indexLetter: 'A'),
Areas(areaCode: 372, name: S.current.c12, indexLetter: 'A'),
Areas(areaCode: 353, name: S.current.c13, indexLetter: 'A'),
Areas(areaCode: 971, name: S.current.c14, indexLetter: 'A'),
Areas(indexLetter: 'B'),
Areas(areaCode: 32, name: S.current.c15, indexLetter: 'B'),
Areas(areaCode: 55, name: S.current.c16, indexLetter: 'B'),
Areas(areaCode: 359, name: S.current.c17, indexLetter: 'B'),
Areas(areaCode: 354, name: S.current.c18, indexLetter: 'B'),
Areas(areaCode: 92, name: S.current.c19, indexLetter: 'B'),
Areas(areaCode: 507, name: S.current.c20, indexLetter: 'B'),
Areas(areaCode: 595, name: S.current.c21, indexLetter: 'B'),
Areas(areaCode: 51, name: S.current.c22, indexLetter: 'B'),
Areas(areaCode: 48, name: S.current.c23, indexLetter: 'B'),
Areas(areaCode: 1787, name: S.current.c24, indexLetter: 'B'),
Areas(indexLetter: 'D'),
Areas(areaCode: 49, name: S.current.c25, indexLetter: 'D'),
Areas(areaCode: 45, name: S.current.c26, indexLetter: 'D'),
Areas(areaCode: 1809, name: S.current.c27, indexLetter: 'D'),
Areas(areaCode: 228, name: S.current.c28, indexLetter: 'D'),
Areas(indexLetter: 'E'),
Areas(areaCode: 593, name: S.current.c29, indexLetter: 'E'),
Areas(areaCode: 7, name: S.current.c30, indexLetter: 'E'),
Areas(indexLetter: 'F'),
Areas(areaCode: 33, name: S.current.c31, indexLetter: 'F'),
Areas(areaCode: 679, name: S.current.c32, indexLetter: 'F'),
Areas(areaCode: 358, name: S.current.c33, indexLetter: 'F'),
Areas(areaCode: 63, name: S.current.c34, indexLetter: 'F'),
Areas(indexLetter: 'G'),
Areas(areaCode: 995, name: S.current.c35, indexLetter: 'G'),
Areas(areaCode: 1473, name: S.current.c36, indexLetter: 'G'),
Areas(indexLetter: 'H'),
Areas(areaCode: 82, name: S.current.c37, indexLetter: 'H'),
Areas(areaCode: 31, name: S.current.c38, indexLetter: 'H'),
Areas(indexLetter: 'J'),
Areas(areaCode: 1, name: S.current.c39, indexLetter: 'J'),
Areas(areaCode: 420, name: S.current.c40, indexLetter: 'J'),
Areas(indexLetter: 'K'),
Areas(areaCode: 385, name: S.current.c41, indexLetter: 'K'),
Areas(areaCode: 974, name: S.current.c42, indexLetter: 'K'),
Areas(indexLetter: 'L'),
Areas(areaCode: 856, name: S.current.c43, indexLetter: 'L'),
Areas(areaCode: 371, name: S.current.c44, indexLetter: 'L'),
Areas(areaCode: 423, name: S.current.c45, indexLetter: 'L'),
Areas(areaCode: 370, name: S.current.c46, indexLetter: 'L'),
Areas(areaCode: 352, name: S.current.c47, indexLetter: 'L'),
Areas(areaCode: 40, name: S.current.c48, indexLetter: 'L'),
Areas(indexLetter: 'M'),
Areas(areaCode: 389, name: S.current.c49, indexLetter: 'M'),
Areas(areaCode: 60, name: S.current.c50, indexLetter: 'M'),
Areas(areaCode: 960, name: S.current.c51, indexLetter: 'M'),
Areas(areaCode: 356, name: S.current.c52, indexLetter: 'M'),
Areas(areaCode: 52, name: S.current.c53, indexLetter: 'M'),
Areas(areaCode: 377, name: S.current.c54, indexLetter: 'M'),
Areas(areaCode: 976, name: S.current.c55, indexLetter: 'M'),
Areas(areaCode: 382, name: S.current.c56, indexLetter: 'M'),
Areas(areaCode: 212, name: S.current.c57, indexLetter: 'M'),
Areas(areaCode: 95, name: S.current.c58, indexLetter: 'M'),
Areas(areaCode: 1, name: S.current.c59, indexLetter: 'M'),
Areas(areaCode: 1284, name: S.current.c60, indexLetter: 'M'),
Areas(indexLetter: 'N'),
Areas(areaCode: 977, name: S.current.c61, indexLetter: 'N'),
Areas(areaCode: 234, name: S.current.c62, indexLetter: 'N'),
Areas(areaCode: 47, name: S.current.c63, indexLetter: 'N'),
Areas(areaCode: 27, name: S.current.c64, indexLetter: 'N'),
Areas(indexLetter: 'P'),
Areas(areaCode: 351, name: S.current.c65, indexLetter: 'P'),
Areas(indexLetter: 'R'),
Areas(areaCode: 81, name: S.current.c66, indexLetter: 'R'),
Areas(areaCode: 46, name: S.current.c67, indexLetter: 'R'),
Areas(areaCode: 41, name: S.current.c68, indexLetter: 'R'),
Areas(indexLetter: 'S'),
Areas(areaCode: 357, name: S.current.c69, indexLetter: 'S'),
Areas(areaCode: 1869, name: S.current.c70, indexLetter: 'S'),
Areas(areaCode: 1758, name: S.current.c71, indexLetter: 'S'),
Areas(areaCode: 966, name: S.current.c72, indexLetter: 'S'),
Areas(areaCode: 421, name: S.current.c73, indexLetter: 'S'),
Areas(areaCode: 386, name: S.current.c74, indexLetter: 'S'),
Areas(areaCode: 94, name: S.current.c75, indexLetter: 'S'),
Areas(areaCode: 249, name: S.current.c76, indexLetter: 'S'),
Areas(indexLetter: 'T'),
Areas(areaCode: 255, name: S.current.c77, indexLetter: 'T'),
Areas(areaCode: 66, name: S.current.c78, indexLetter: 'T'),
Areas(areaCode: 676, name: S.current.c79, indexLetter: 'T'),
Areas(areaCode: 216, name: S.current.c80, indexLetter: 'T'),
Areas(areaCode: 90, name: S.current.c81, indexLetter: 'T'),
Areas(indexLetter: 'W'),
Areas(areaCode: 380, name: S.current.c82, indexLetter: 'W'),
Areas(areaCode: 598, name: S.current.c83, indexLetter: 'W'),
Areas(indexLetter: 'X'),
Areas(areaCode: 30, name: S.current.c84, indexLetter: 'X'),
Areas(areaCode: 36, name: S.current.c85, indexLetter: 'X'),
Areas(areaCode: 64, name: S.current.c86, indexLetter: 'X'),
Areas(areaCode: 65, name: S.current.c87, indexLetter: 'X'),
Areas(areaCode: 34, name: S.current.c88, indexLetter: 'X'),
Areas(areaCode: 852, name: S.current.c89, indexLetter: 'X'),
Areas(indexLetter: 'Y'),
Areas(areaCode: 91, name: S.current.c90, indexLetter: 'Y'),
Areas(areaCode: 62, name: S.current.c91, indexLetter: 'Y'),
Areas(areaCode: 972, name: S.current.c92, indexLetter: 'Y'),
Areas(areaCode: 39, name: S.current.c93, indexLetter: 'Y'),
Areas(areaCode: 44, name: S.current.c94, indexLetter: 'Y'),
Areas(areaCode: 84, name: S.current.c95, indexLetter: 'Y'),
Areas(indexLetter: 'Z'),
Areas(areaCode: 56, name: S.current.c96, indexLetter: 'Z'),
Areas(areaCode: 853, name: S.current.c97, indexLetter: 'Z'),
Areas(areaCode: 886, name: S.current.c98, indexLetter: 'Z'),
Areas(areaCode: 260, name: S.current.c99, indexLetter: 'Z'),
];
2.给列表添加appbar
import 'package:generated/l10n.dart';
import 'package:widget/custom_appbar.dart';
import 'package:widget/login/login_area_list_wdiget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class LoginAreaSelectPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomAppBar(
backgroundColor: Color(0xff5dc8b6),
leading: IconButton(
onPressed: () => Navigator.pop(context),
icon: Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
),
title: Text(
S.current.xuanzeguojia,
style: TextStyle(
fontSize: 38.sp,
fontWeight: FontWeight.w600,
color: Colors.white),
),
centerTitle: true,
),
body: LoginAreaListWidget()
,
);
}
}
3.引用
var areaCode;
GestureDetector(
onTap: () async {
var result = await NavigatorUtil.push(LoginAreaSelectPage());
if (result != null) {
setState(() {
areaCode = result;
});
}
},
child: Container(width:100,height:50,color:Colors.red));