|
- import 'package:cached_network_image/cached_network_image.dart';
- import 'package:chat/data/UserData.dart';
- import 'package:chat/data/constants.dart';
- import 'package:chat/generated/i18n.dart';
- import 'package:chat/models/group_info_model.dart';
- import 'package:chat/utils/CustomUI.dart';
- import 'package:chat/utils/group_member_model.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
-
- class _MemberItem extends StatelessWidget {
- _MemberItem({
- @required this.avatar,
- @required this.title,
- @required this.userId,
- this.groupTitle,
- this.onPressed,
- this.gradient,
- this.iconCode,
- this.isShowDivder: true,
- });
- final int userId;
- final int iconCode;
- final String avatar;
- final String title;
- final String groupTitle;
- final VoidCallback onPressed;
- final Gradient gradient;
- final bool isShowDivder;
-
- static double _height(bool hasGroupTitle) {
- final _buttonHeight = MARGIN_VERTICAL * 2 +
- Constants.ContactAvatarSize +
- Constants.DividerWidth;
- if (hasGroupTitle) {
- return _buttonHeight + GROUP_TITLE_HEIGHT;
- } else {
- return _buttonHeight;
- }
- }
-
- @override
- Widget build(BuildContext context) {
- Widget _avatarIcon;
- if (iconCode == null) {
- _avatarIcon = ClipRRect(
- borderRadius: BorderRadius.circular(6),
- child: CachedNetworkImage(
- imageUrl: this.avatar,
- width: Constants.ContactAvatarSize,
- height: Constants.ContactAvatarSize,
- ));
- } else {
- _avatarIcon = Container(
- width: Constants.ContactAvatarSize,
- height: Constants.ContactAvatarSize,
- decoration: BoxDecoration(
- gradient: gradient, borderRadius: BorderRadius.circular(6)),
- child: Icon(
- IconData(this.iconCode, fontFamily: Constants.IconFontFamily),
- color: Colors.white,
- ),
- );
- }
-
- Widget _button = Container(
- padding: const EdgeInsets.symmetric(
- vertical: MARGIN_VERTICAL, horizontal: 16.0),
- decoration: BoxDecoration(color: Colors.white),
- child: Row(
- children: <Widget>[
- _avatarIcon,
- SizedBox(width: 10.0),
- Text(title, textScaleFactor: 1.0,),
- ],
- ),
- );
-
- //分组标签
- Widget _itemBody;
- if (this.groupTitle != null) {
- _itemBody = Column(
- children: <Widget>[
- Container(
- height: GROUP_TITLE_HEIGHT,
- padding: EdgeInsets.only(left: 16.0, right: 16.0),
- color: const Color(AppColors.ContactGroupTitleBgColor),
- alignment: Alignment.centerLeft,
- child:
- Text(this.groupTitle, textScaleFactor: 1.0,style: AppStyles.GroupTitleItemTextStyle),
- ),
- _button,
- ],
- );
- } else {
- _itemBody = _button;
- }
-
- return InkWell(
- onTap: onPressed,
- child: Container(
- color: Colors.white,
- child: Column(
- children: <Widget>[
- _itemBody,
- isShowDivder
- ? Container(
- height: 1,
- color: const Color(0xFFF3F3F3),
- margin: EdgeInsets.only(
- left: 26 + Constants.ContactAvatarSize),
- )
- : Container()
- ],
- )));
- }
- }
-
- class AlterSelectPage extends StatefulWidget {
- final GroupInfoModel groupInfoModel;
- AlterSelectPage(this.groupInfoModel);
- @override
- _AlterSelectPageState createState() => _AlterSelectPageState();
-
- static Future<GroupMemberModel> pickAlterUser(
- BuildContext context, GroupInfoModel groupInfoModel) async {
- var results = await Navigator.of(context).push(
- MaterialPageRoute<dynamic>(
- builder: (BuildContext context) {
- return AlterSelectPage(groupInfoModel);
- },
- ),
- );
-
- return results;
- }
- }
-
- class _AlterSelectPageState extends State<AlterSelectPage> {
- List<GroupMemberModel> members = []; //除自己外的其他成员
- bool _hasdeleteIcon = false; //是否在搜索状态
- TextEditingController _txtCtrl = TextEditingController();
- ScrollController _scrollController = ScrollController();
- List<GroupMemberModel> searchList = [];
- final Map _letterPosMap = {INDEX_BAR_WORDS[0]: 0.0};
-
- FocusNode focusNode = FocusNode();
-
- String _currentLetter = '';
-
- @override
- void initState() {
- super.initState();
- print('AlterSelectPage initState');
- var myId = UserData().basicInfo.userId;
- for (var member in widget.groupInfoModel.members) {
- if (member.memberId != myId && member.inGroup > 0) {
- member.getNameTag();
- members.add(member);
- }
- }
- }
-
- @override
- void dispose() {
-
- focusNode.unfocus();
- _scrollController.dispose();
- _txtCtrl.dispose();
- super.dispose();
- }
-
- updateIndexPos(List<GroupMemberModel> friendList) {
- //计算用于 IndexBar 进行定位的关键通讯录列表项的位置
- double _totalPos = 0.0;
- for (var i = 0; i < friendList.length; i++) {
- bool _hasGroupTitle = true;
- if (i > 0 &&
- friendList[i].nameTag.compareTo(friendList[i - 1].nameTag) == 0) {
- _hasGroupTitle = false;
- }
-
- if (_hasGroupTitle) {
- _letterPosMap[friendList[i].nameTag] = _totalPos;
- }
- _totalPos += _MemberItem._height(_hasGroupTitle);
- }
- }
-
- String getLetter(BuildContext context, double tileHeight, Offset globalPos) {
- RenderBox _box = context.findRenderObject();
- var local = _box.globalToLocal(globalPos);
- int index = (local.dy ~/ tileHeight).clamp(0, INDEX_BAR_WORDS.length - 1);
- return INDEX_BAR_WORDS[index];
- }
-
- void _jumpToIndex(String letter) {
- if (_letterPosMap.isNotEmpty) {
- final _pos = _letterPosMap[letter];
- if (_pos != null) {
- _scrollController.animateTo(_letterPosMap[letter],
- curve: Curves.easeInOut, duration: Duration(microseconds: 200));
- }
- }
- }
-
- Widget _buildIndexBar(BuildContext context, BoxConstraints constraints) {
- final List<Widget> _letters = INDEX_BAR_WORDS.map((String word) {
- return Expanded(
- child: Container(
- margin: EdgeInsets.only(right: 5),
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- color:
- _currentLetter == word ? Colors.blue : Colors.transparent,
- ),
- alignment: Alignment.center,
- padding: EdgeInsets.all(2),
- width: 20,
- child: Text(
- word,
- textScaleFactor: 1.0,
- style: TextStyle(
- fontSize: 10,
-
- color:
- _currentLetter == word ? Colors.white : Colors.black),
- )));
- }).toList();
-
- final _totalHeight = constraints.biggest.height;
- final _tileHeight = _totalHeight / _letters.length;
- return GestureDetector(
- onVerticalDragDown: (DragDownDetails details) {
- setState(() {
- _currentLetter =
- getLetter(context, _tileHeight, details.globalPosition);
- _jumpToIndex(_currentLetter);
- });
- },
- onVerticalDragEnd: (DragEndDetails details) {
- setState(() {
- //_indexBarBgColor = Colors.transparent;
- _currentLetter = null;
- });
- },
- onVerticalDragCancel: () {
- setState(() {
- //_indexBarBgColor = Colors.transparent;
- _currentLetter = null;
- });
- },
- onVerticalDragUpdate: (DragUpdateDetails details) {
- setState(() {
- //var _letter = getLetter(context, _tileHeight, details.globalPosition);
- _currentLetter =
- getLetter(context, _tileHeight, details.globalPosition);
- _jumpToIndex(_currentLetter);
- });
- },
- child: Column(
- children: _letters,
- ),
- );
- }
-
- @override
- Widget build(BuildContext context) {
- final List<Widget> _body = [];
-
- if (!_hasdeleteIcon) {
-
- members.sort((a, b) => a.nameTag.compareTo(b.nameTag));
-
- updateIndexPos(members);
- _body.addAll([
- ListView.builder(
- controller: _scrollController,
- itemBuilder: (BuildContext context, int index) {
- bool _isGroupTitle = true;
- GroupMemberModel _contact = members[index];
-
- if (index >= 1 &&
- _contact.nameTag == members[index - 1].nameTag) {
- _isGroupTitle = false;
- }
-
- return _MemberItem(
- userId: _contact.memberId,
- avatar: _contact.avtar,
- title: _contact.refName,
- isShowDivder: _isGroupTitle,
- onPressed: () {
- Navigator.of(context).pop(_contact);
- },
- groupTitle: _isGroupTitle ? _contact.nameTag : null);
- },
- itemCount: members.length),
- Positioned(
- width: Constants.IndexBarWidth,
- right: 0.0,
- top: 0.0,
- bottom: 0.0,
- child: Container(
- child: LayoutBuilder(
- builder: _buildIndexBar,
- ),
- ),
- )
- ]);
- } else {
- _body.add(ListView.builder(
- controller: _scrollController,
- itemBuilder: (BuildContext context, int index) {
- GroupMemberModel _contact = searchList[index];
-
- return _MemberItem(
- userId: _contact.memberId,
- avatar: _contact.avtar,
- title: _contact.refName,
- isShowDivder: true,
- onPressed: () {
- Navigator.of(context).pop(_contact);
- },
- groupTitle: null);
- },
- itemCount: searchList.length,
- ));
- }
-
- if (_currentLetter != null &&
- _currentLetter.isNotEmpty &&
- !_hasdeleteIcon) {
- _body.add(Center(
- child: Container(
- width: Constants.IndexLetterBoxSize,
- height: Constants.IndexLetterBoxSize,
- decoration: BoxDecoration(
- color: AppColors.IndexLetterBoxBgColor,
- borderRadius: BorderRadius.all(
- Radius.circular(Constants.IndexLetterBoxRadius)),
- ),
- child: Center(
- child:
- Text(_currentLetter, textScaleFactor: 1.0, style: AppStyles.IndexLetterBoxTextStyle),
- ),
- ),
- ));
- }
-
- return Scaffold(
- resizeToAvoidBottomPadding: false,
- backgroundColor: AppColors.NewAppbarBgColor,
- appBar: AppBar(
- title: Text(I18n.of(context).select_notice_people),
- centerTitle: true,
- elevation: 1,
- leading: CustomUI.buildCustomLeading(context),
- bottom: PreferredSize(
- preferredSize: Size.fromHeight(49),
- child: Container(
- alignment: Alignment.center,
- margin: EdgeInsets.only(bottom: 14, left: 12.5, right: 12.5),
- height: 35,
- decoration: BoxDecoration(
- color: const Color(0xFFEEEEEE),
- borderRadius: BorderRadius.all(Radius.circular(8))),
- child: TextField(
- keyboardAppearance: Brightness.light,
- keyboardType: TextInputType.text,
- textInputAction: TextInputAction.search,
- controller: _txtCtrl,
- cursorColor: Constants.BlueTextColor,
- maxLines: 1,
- style: TextStyle(
- textBaseline: TextBaseline.alphabetic, fontSize: 14.5),
- autofocus: false,
- inputFormatters: [
- LengthLimitingTextInputFormatter(50),
- ],
- focusNode: focusNode,
- decoration: InputDecoration(
- hintText: I18n.of(context).search,
- hintStyle: TextStyle(fontSize: 14.5),
- prefixIcon: Icon(
- IconData(
- 0xe664,
- fontFamily: Constants.IconFontFamily,
- ),
- color: const Color(0xFFA0A0A0),
- size: 18,
- ),
- suffixIcon: Padding(
- padding: EdgeInsetsDirectional.only(
- start: 2.0, end: _hasdeleteIcon ? 20.0 : 0),
- child: _hasdeleteIcon
- ? new InkWell(
- onTap: (() {
- setState(() {
- WidgetsBinding.instance
- .addPostFrameCallback(
- (_) => _txtCtrl.clear());
- _hasdeleteIcon = false;
- });
- }),
- child: Icon(
- Icons.clear,
- size: 18.0,
- color: Constants.BlackTextColor,
- ))
- : new Text('')),
- filled: true,
- fillColor: Colors.transparent,
- border: InputBorder.none,
- ),
- onChanged: (str) async {
- setState(() {
- if (str.isEmpty) {
- _hasdeleteIcon = false;
- } else {
- _hasdeleteIcon = true;
- searchList = CustomUI().getSearchResult(
- str, members == null ? [] : members);
- }
- });
- },
- onEditingComplete: () {}),
- )),
- ),
- body: Stack(
- children: _body,
- ));
- }
- }
|