Showing
6 changed files
with
578 additions
and
164 deletions
| @@ -22,7 +22,9 @@ class UserHistoryEntity extends Object { | @@ -22,7 +22,9 @@ class UserHistoryEntity extends Object { | ||
| 22 | @JsonKey(name: 'cusdem') | 22 | @JsonKey(name: 'cusdem') |
| 23 | String cusdem; | 23 | String cusdem; |
| 24 | 24 | ||
| 25 | - String pinyin; | 25 | + List<String> pinyinList; //全拼数组 |
| 26 | + String pinyin; //全拼字母 | ||
| 27 | + String pinyinFirst; //首字母 | ||
| 26 | 28 | ||
| 27 | UserHistoryEntity( | 29 | UserHistoryEntity( |
| 28 | this.id, | 30 | this.id, |
| @@ -2,10 +2,12 @@ import 'package:flutter/material.dart'; | @@ -2,10 +2,12 @@ import 'package:flutter/material.dart'; | ||
| 2 | import 'package:flutter_easyrefresh/easy_refresh.dart'; | 2 | import 'package:flutter_easyrefresh/easy_refresh.dart'; |
| 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; | 3 | import 'package:flutter_screenutil/flutter_screenutil.dart'; |
| 4 | import 'package:one_key/constant/state.dart'; | 4 | import 'package:one_key/constant/state.dart'; |
| 5 | +import 'package:one_key/models/user_history_entity.dart'; | ||
| 5 | import 'package:one_key/provider/contant_show_model.dart'; | 6 | import 'package:one_key/provider/contant_show_model.dart'; |
| 6 | import 'package:one_key/provider/user_model.dart'; | 7 | import 'package:one_key/provider/user_model.dart'; |
| 7 | import 'package:one_key/res/colors.dart'; | 8 | import 'package:one_key/res/colors.dart'; |
| 8 | import 'package:one_key/utils/dialog_util.dart'; | 9 | import 'package:one_key/utils/dialog_util.dart'; |
| 10 | +import 'package:one_key/utils/utils.dart'; | ||
| 9 | import 'package:one_key/widgets/MyDivider.dart'; | 11 | import 'package:one_key/widgets/MyDivider.dart'; |
| 10 | 12 | ||
| 11 | import 'package:one_key/widgets/page_exception.dart'; | 13 | import 'package:one_key/widgets/page_exception.dart'; |
| @@ -40,6 +42,344 @@ class _ContantLeftPageState extends State<ContantLeftPage> { | @@ -40,6 +42,344 @@ class _ContantLeftPageState extends State<ContantLeftPage> { | ||
| 40 | await contantShowModel.getUserHistorys(context, params); | 42 | await contantShowModel.getUserHistorys(context, params); |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 45 | + _getWidget(String title, String key) { | ||
| 46 | + return RichText( | ||
| 47 | + text: TextSpan(children: getTextSpanList(title, searchContent: key))); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + ///关键字在前面布局 | ||
| 51 | + _startPlaceWidget( | ||
| 52 | + String title, String key, UserHistoryEntity userHistoryEntity) { | ||
| 53 | + String keyTemp = ''; | ||
| 54 | + if (Utils.isChinese(key)) { | ||
| 55 | + keyTemp = key; | ||
| 56 | + } else { | ||
| 57 | + String name = | ||
| 58 | + userHistoryEntity.rname == null || userHistoryEntity.rname == '' | ||
| 59 | + ? '' | ||
| 60 | + : userHistoryEntity.rname; | ||
| 61 | + String pinyinFirst = userHistoryEntity.pinyinFirst; | ||
| 62 | + List<String> pinyinList = userHistoryEntity.pinyinList; | ||
| 63 | + | ||
| 64 | + if (pinyinList.indexOf(key) != -1) { | ||
| 65 | + keyTemp = name.substring( | ||
| 66 | + pinyinList.indexOf(key), pinyinList.indexOf(key) + 1); | ||
| 67 | + } else if (pinyinFirst.contains(key)) { | ||
| 68 | + keyTemp = name.substring( | ||
| 69 | + pinyinFirst.indexOf(key), pinyinFirst.indexOf(key) + 1); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + print(keyTemp); | ||
| 73 | + } | ||
| 74 | + return _getWidget(title, keyTemp); | ||
| 75 | + // return RichText( | ||
| 76 | + // maxLines: 1, | ||
| 77 | + // overflow: TextOverflow.ellipsis, | ||
| 78 | + // text: TextSpan( | ||
| 79 | + // children: [ | ||
| 80 | + // TextSpan( | ||
| 81 | + // text: keyTemp, | ||
| 82 | + // style: TextStyle( | ||
| 83 | + // fontSize: ScreenUtil().setSp(32), | ||
| 84 | + // color: MyColours.color_199095), | ||
| 85 | + // ), | ||
| 86 | + // TextSpan( | ||
| 87 | + // text: title.replaceAll(keyTemp, ''), | ||
| 88 | + // style: TextStyle( | ||
| 89 | + // fontSize: ScreenUtil().setSp(32), | ||
| 90 | + // color: MyColours.color_333333), | ||
| 91 | + // ), | ||
| 92 | + // ], | ||
| 93 | + // )); | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + // ///关键字在后面布局 | ||
| 97 | + // _endlaceWidget( | ||
| 98 | + // String title, String key, UserHistoryEntity userHistoryEntity) { | ||
| 99 | + // String keyTemp = ''; | ||
| 100 | + // if (Utils.isChinese(key)) { | ||
| 101 | + // keyTemp = key; | ||
| 102 | + // } else if (Utils.isPinyin(key)) { | ||
| 103 | + // String name = | ||
| 104 | + // userHistoryEntity.rname == null || userHistoryEntity.rname == '' | ||
| 105 | + // ? '' | ||
| 106 | + // : userHistoryEntity.rname; | ||
| 107 | + // String pinyinFirst = userHistoryEntity.pinyinFirst; | ||
| 108 | + // List<String> pinyinList = userHistoryEntity.pinyinList; | ||
| 109 | + // String pinyin = userHistoryEntity.pinyin; | ||
| 110 | + // if (pinyinList.indexOf(key) != -1) { | ||
| 111 | + // keyTemp = name.substring( | ||
| 112 | + // pinyinList.indexOf(key), pinyinList.indexOf(key) + 1); | ||
| 113 | + // } else if (pinyinFirst.contains(key)) { | ||
| 114 | + // keyTemp = name.substring( | ||
| 115 | + // pinyinFirst.indexOf(key), pinyinFirst.indexOf(key) + 1); | ||
| 116 | + // } | ||
| 117 | + // print(keyTemp); | ||
| 118 | + // } | ||
| 119 | + // return RichText( | ||
| 120 | + // maxLines: 1, | ||
| 121 | + // overflow: TextOverflow.ellipsis, | ||
| 122 | + // text: TextSpan( | ||
| 123 | + // children: [ | ||
| 124 | + // TextSpan( | ||
| 125 | + // text: title.replaceAll(keyTemp, ''), | ||
| 126 | + // style: TextStyle( | ||
| 127 | + // fontSize: ScreenUtil().setSp(32), | ||
| 128 | + // color: MyColours.color_333333), | ||
| 129 | + // ), | ||
| 130 | + // TextSpan( | ||
| 131 | + // text: keyTemp, | ||
| 132 | + // style: TextStyle( | ||
| 133 | + // fontSize: ScreenUtil().setSp(32), | ||
| 134 | + // color: MyColours.color_199095), | ||
| 135 | + // ), | ||
| 136 | + // ], | ||
| 137 | + // )); | ||
| 138 | + // } | ||
| 139 | + | ||
| 140 | + // ///关键字在中间布局 | ||
| 141 | + // _middlePlaceWidget( | ||
| 142 | + // String title, String key, UserHistoryEntity userHistoryEntity) { | ||
| 143 | + // String keyTemp = ''; | ||
| 144 | + // if (Utils.isChinese(key)) { | ||
| 145 | + // keyTemp = key; | ||
| 146 | + // } else if (Utils.isPinyin(key)) { | ||
| 147 | + // String name = | ||
| 148 | + // userHistoryEntity.rname == null || userHistoryEntity.rname == '' | ||
| 149 | + // ? '' | ||
| 150 | + // : userHistoryEntity.rname; | ||
| 151 | + // String pinyinFirst = userHistoryEntity.pinyinFirst; | ||
| 152 | + // List<String> pinyinList = userHistoryEntity.pinyinList; | ||
| 153 | + // String pinyin = userHistoryEntity.pinyin; | ||
| 154 | + // if (pinyinFirst.contains(key)) { | ||
| 155 | + // keyTemp = name.substring( | ||
| 156 | + // pinyinFirst.indexOf(key), pinyinFirst.indexOf(key) + 1); | ||
| 157 | + // } else if (pinyinList.indexOf(key) != -1) { | ||
| 158 | + // keyTemp = name.substring( | ||
| 159 | + // pinyinList.indexOf(key), pinyinList.indexOf(key) + 1); | ||
| 160 | + // } | ||
| 161 | + // print(keyTemp); | ||
| 162 | + // } | ||
| 163 | + // return RichText( | ||
| 164 | + // maxLines: 1, | ||
| 165 | + // overflow: TextOverflow.ellipsis, | ||
| 166 | + // text: TextSpan( | ||
| 167 | + // children: [ | ||
| 168 | + // TextSpan( | ||
| 169 | + // text: title.substring(0, title.indexOf(keyTemp)), | ||
| 170 | + // style: TextStyle( | ||
| 171 | + // fontSize: ScreenUtil().setSp(32), | ||
| 172 | + // color: MyColours.color_333333), | ||
| 173 | + // ), | ||
| 174 | + // TextSpan( | ||
| 175 | + // text: keyTemp, | ||
| 176 | + // style: TextStyle( | ||
| 177 | + // fontSize: ScreenUtil().setSp(32), | ||
| 178 | + // color: MyColours.color_199095), | ||
| 179 | + // ), | ||
| 180 | + // TextSpan( | ||
| 181 | + // text: title.substring( | ||
| 182 | + // title.lastIndexOf(keyTemp) + keyTemp.length, title.length), | ||
| 183 | + // style: TextStyle( | ||
| 184 | + // fontSize: ScreenUtil().setSp(32), | ||
| 185 | + // color: MyColours.color_333333)), | ||
| 186 | + // ], | ||
| 187 | + // ), | ||
| 188 | + // ); | ||
| 189 | + // } | ||
| 190 | + | ||
| 191 | + List<TextSpan> getTextSpanList(String textContent, | ||
| 192 | + {String searchContent = '', | ||
| 193 | + String frontContent = '', | ||
| 194 | + int fontSize = 32, | ||
| 195 | + Color fontColor = MyColours.color_333333, | ||
| 196 | + Color selectFontColor = MyColours.color_199095}) { | ||
| 197 | + List<TextSpan> textSpanList = []; | ||
| 198 | + | ||
| 199 | + if (frontContent.isEmpty == false) { | ||
| 200 | + textSpanList.add(TextSpan( | ||
| 201 | + text: frontContent, | ||
| 202 | + style: TextStyle( | ||
| 203 | + fontSize: ScreenUtil().setSp(fontSize), color: fontColor))); | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + ///搜索内容不为空并且 显示内容中存在与搜索内容相同的文字 | ||
| 207 | + if (searchContent != null && | ||
| 208 | + searchContent.isEmpty == false && | ||
| 209 | + textContent.contains(searchContent)) { | ||
| 210 | + List<Map> _strMapList = []; | ||
| 211 | + bool _isContains = true; | ||
| 212 | + while (_isContains) { | ||
| 213 | + int startIndex = textContent.indexOf(searchContent); | ||
| 214 | + String showStr = textContent.substring( | ||
| 215 | + startIndex, startIndex + searchContent.length); | ||
| 216 | + Map _strMap; | ||
| 217 | + if (startIndex > 0) { | ||
| 218 | + String normalStr = textContent.substring(0, startIndex); | ||
| 219 | + _strMap = Map(); | ||
| 220 | + _strMap['content'] = normalStr; | ||
| 221 | + _strMap['isHighlight'] = false; | ||
| 222 | + _strMapList.add(_strMap); | ||
| 223 | + } | ||
| 224 | + _strMap = Map(); | ||
| 225 | + _strMap['content'] = showStr; | ||
| 226 | + _strMap['isHighlight'] = true; | ||
| 227 | + _strMapList.add(_strMap); | ||
| 228 | + textContent = textContent.substring( | ||
| 229 | + startIndex + searchContent.length, textContent.length); | ||
| 230 | + | ||
| 231 | + _isContains = textContent.contains(searchContent); | ||
| 232 | + if (!_isContains && textContent != '') { | ||
| 233 | + _strMap = Map(); | ||
| 234 | + _strMap['content'] = textContent; | ||
| 235 | + _strMap['isHighlight'] = false; | ||
| 236 | + _strMapList.add(_strMap); | ||
| 237 | + } | ||
| 238 | + } | ||
| 239 | + _strMapList.forEach((map) { | ||
| 240 | + textSpanList.add(TextSpan( | ||
| 241 | + text: map['content'], | ||
| 242 | + style: TextStyle( | ||
| 243 | + fontSize: ScreenUtil().setSp(fontSize), | ||
| 244 | + color: map['isHighlight'] ? selectFontColor : fontColor))); | ||
| 245 | + }); | ||
| 246 | + } else { | ||
| 247 | + ///正常显示所有文字 | ||
| 248 | + textSpanList.add(TextSpan( | ||
| 249 | + text: textContent, | ||
| 250 | + style: | ||
| 251 | + TextStyle(fontSize: ScreenUtil().setSp(fontSize), color: fontColor), | ||
| 252 | + )); | ||
| 253 | + } | ||
| 254 | + return textSpanList; | ||
| 255 | + } | ||
| 256 | + | ||
| 257 | + Widget _getNameWidget(UserHistoryEntity userHistoryEntity) { | ||
| 258 | + String name = | ||
| 259 | + userHistoryEntity.rname == null || userHistoryEntity.rname == '' | ||
| 260 | + ? '' | ||
| 261 | + : userHistoryEntity.rname; | ||
| 262 | + // String phone = | ||
| 263 | + // userHistoryEntity.phone == null || userHistoryEntity.phone == '' | ||
| 264 | + // ? '' | ||
| 265 | + // : userHistoryEntity.phone; | ||
| 266 | + String key = contantShowModel.controller.text; | ||
| 267 | + String pinyinFirst = userHistoryEntity.pinyinFirst; | ||
| 268 | + List<String> pinyinList = userHistoryEntity.pinyinList; | ||
| 269 | + String pinyin = userHistoryEntity.pinyin; | ||
| 270 | + if (key == '') { | ||
| 271 | + return Text(name, | ||
| 272 | + style: TextStyle( | ||
| 273 | + color: MyColours.color_333333, fontSize: ScreenUtil().setSp(32))); | ||
| 274 | + } else { | ||
| 275 | + if (Utils.isChinese(key) || Utils.isNum(key)) { | ||
| 276 | + return name.contains(key) && name.length != key.length | ||
| 277 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 278 | + : Text(name, | ||
| 279 | + style: TextStyle( | ||
| 280 | + color: name.length == key.length | ||
| 281 | + ? MyColours.color_199095 | ||
| 282 | + : MyColours.color_333333, | ||
| 283 | + fontSize: ScreenUtil().setSp(32))); | ||
| 284 | + } else if (Utils.isPinyin(key)) { | ||
| 285 | + if (!pinyinFirst.contains(key) && !pinyinList.contains(key)) { | ||
| 286 | + return Text(name, | ||
| 287 | + style: TextStyle( | ||
| 288 | + color: MyColours.color_333333, | ||
| 289 | + fontSize: ScreenUtil().setSp(32))); | ||
| 290 | + } else { | ||
| 291 | + if (pinyinFirst.contains(key)) { | ||
| 292 | + return pinyinFirst.contains(key) && pinyinFirst.length != key.length | ||
| 293 | + ? Row( | ||
| 294 | + children: <Widget>[ | ||
| 295 | + pinyinFirst.startsWith(key) | ||
| 296 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 297 | + : Text(''), | ||
| 298 | + (pinyinFirst.length != key.length && | ||
| 299 | + pinyinFirst.endsWith(key)) | ||
| 300 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 301 | + : Text(''), | ||
| 302 | + (!pinyinFirst.endsWith(key) && | ||
| 303 | + !pinyinFirst.startsWith(key)) | ||
| 304 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 305 | + : Text('') | ||
| 306 | + ], | ||
| 307 | + ) | ||
| 308 | + : Text(name, | ||
| 309 | + style: TextStyle( | ||
| 310 | + color: pinyinFirst.length == key.length | ||
| 311 | + ? MyColours.color_199095 | ||
| 312 | + : MyColours.color_333333, | ||
| 313 | + fontSize: ScreenUtil().setSp(32))); | ||
| 314 | + } else if (pinyinList.contains(key)) { | ||
| 315 | + return pinyinList.contains(key) && pinyin.length != key.length | ||
| 316 | + ? Row( | ||
| 317 | + children: <Widget>[ | ||
| 318 | + pinyin.startsWith(key) | ||
| 319 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 320 | + : Text(''), | ||
| 321 | + pinyin.endsWith(key) | ||
| 322 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 323 | + : Text(''), | ||
| 324 | + (!pinyin.endsWith(key) && !pinyin.startsWith(key)) | ||
| 325 | + ? _startPlaceWidget(name, key, userHistoryEntity) | ||
| 326 | + : Text('') | ||
| 327 | + ], | ||
| 328 | + ) | ||
| 329 | + : Text(name, | ||
| 330 | + style: TextStyle( | ||
| 331 | + color: MyColours.color_333333, | ||
| 332 | + fontSize: ScreenUtil().setSp(32))); | ||
| 333 | + } | ||
| 334 | + } | ||
| 335 | + } else { | ||
| 336 | + return Text(name, | ||
| 337 | + style: TextStyle( | ||
| 338 | + color: MyColours.color_333333, | ||
| 339 | + fontSize: ScreenUtil().setSp(32))); | ||
| 340 | + } | ||
| 341 | + } | ||
| 342 | + } | ||
| 343 | + | ||
| 344 | + Widget _getPhoneWidget(UserHistoryEntity userHistoryEntity) { | ||
| 345 | + String phone = | ||
| 346 | + userHistoryEntity.phone == null || userHistoryEntity.phone == '' | ||
| 347 | + ? '' | ||
| 348 | + : userHistoryEntity.phone; | ||
| 349 | + String key = contantShowModel.controller.text; | ||
| 350 | + String pinyinFirst = userHistoryEntity.pinyinFirst; | ||
| 351 | + List<String> pinyinList = userHistoryEntity.pinyinList; | ||
| 352 | + String pinyin = userHistoryEntity.pinyin; | ||
| 353 | + if (key == '') { | ||
| 354 | + return Text(phone, | ||
| 355 | + style: TextStyle( | ||
| 356 | + color: MyColours.color_999999, fontSize: ScreenUtil().setSp(30))); | ||
| 357 | + } else { | ||
| 358 | + if (Utils.isNum(key)) { | ||
| 359 | + return phone.contains(key) && phone.length != key.length | ||
| 360 | + ? Row( | ||
| 361 | + children: <Widget>[ | ||
| 362 | + phone.startsWith(key) || | ||
| 363 | + pinyinFirst.startsWith(key) || | ||
| 364 | + pinyinList[0] == key | ||
| 365 | + ? _startPlaceWidget(phone, key, userHistoryEntity) | ||
| 366 | + : Text(''), | ||
| 367 | + (phone.length != key.length && phone.endsWith(key)) | ||
| 368 | + ? _startPlaceWidget(phone, key, userHistoryEntity) | ||
| 369 | + : Text(''), | ||
| 370 | + (!phone.endsWith(key) && !phone.startsWith(key)) | ||
| 371 | + ? _startPlaceWidget(phone, key, userHistoryEntity) | ||
| 372 | + : Text('') | ||
| 373 | + ], | ||
| 374 | + ) | ||
| 375 | + : Text(phone, | ||
| 376 | + style: TextStyle( | ||
| 377 | + color: MyColours.color_999999, | ||
| 378 | + fontSize: ScreenUtil().setSp(30))); | ||
| 379 | + } | ||
| 380 | + } | ||
| 381 | + } | ||
| 382 | + | ||
| 43 | @override | 383 | @override |
| 44 | Widget build(BuildContext context) { | 384 | Widget build(BuildContext context) { |
| 45 | contantShowModel = Provider.of<ContantShowModel>(context, listen: true); | 385 | contantShowModel = Provider.of<ContantShowModel>(context, listen: true); |
| @@ -63,6 +403,11 @@ class _ContantLeftPageState extends State<ContantLeftPage> { | @@ -63,6 +403,11 @@ class _ContantLeftPageState extends State<ContantLeftPage> { | ||
| 63 | return ListView.builder( | 403 | return ListView.builder( |
| 64 | itemCount: model.userHistorysShow.length, | 404 | itemCount: model.userHistorysShow.length, |
| 65 | itemBuilder: (BuildContext context, int index) { | 405 | itemBuilder: (BuildContext context, int index) { |
| 406 | + String phone = model.userHistorysShow[index].phone == null || | ||
| 407 | + model.userHistorysShow[index].phone == '' | ||
| 408 | + ? '' | ||
| 409 | + : model.userHistorysShow[index].phone; | ||
| 410 | + | ||
| 66 | return InkWell( | 411 | return InkWell( |
| 67 | onTap: () { | 412 | onTap: () { |
| 68 | if (model.userHistorysShow[index].phone != null && | 413 | if (model.userHistorysShow[index].phone != null && |
| @@ -100,23 +445,9 @@ class _ContantLeftPageState extends State<ContantLeftPage> { | @@ -100,23 +445,9 @@ class _ContantLeftPageState extends State<ContantLeftPage> { | ||
| 100 | child: Column( | 445 | child: Column( |
| 101 | crossAxisAlignment: CrossAxisAlignment.start, | 446 | crossAxisAlignment: CrossAxisAlignment.start, |
| 102 | children: [ | 447 | children: [ |
| 103 | - Text( | ||
| 104 | - model.userHistorysShow[index].rname == null || | ||
| 105 | - model.userHistorysShow[index].rname == '' | ||
| 106 | - ? '' | ||
| 107 | - : model.userHistorysShow[index].rname, | ||
| 108 | - style: TextStyle( | ||
| 109 | - color: MyColours.color_333333, | ||
| 110 | - fontSize: ScreenUtil().setSp(32))), | 448 | + _getNameWidget(model.userHistorysShow[index]), |
| 111 | VEmptyView(10), | 449 | VEmptyView(10), |
| 112 | - Text( | ||
| 113 | - model.userHistorysShow[index].phone == null || | ||
| 114 | - model.userHistorysShow[index].phone == '' | ||
| 115 | - ? '' | ||
| 116 | - : model.userHistorysShow[index].phone, | ||
| 117 | - style: TextStyle( | ||
| 118 | - color: MyColours.color_999999, | ||
| 119 | - fontSize: ScreenUtil().setSp(30))) | 450 | + // _getPhoneWidget(model.userHistorysShow[index]) |
| 120 | ], | 451 | ], |
| 121 | ), | 452 | ), |
| 122 | ) | 453 | ) |
| @@ -25,7 +25,7 @@ class _ContactListPageState extends State<ContactListPage> | @@ -25,7 +25,7 @@ class _ContactListPageState extends State<ContactListPage> | ||
| 25 | List<Contact> _contacts; | 25 | List<Contact> _contacts; |
| 26 | List _tabBarTitle; | 26 | List _tabBarTitle; |
| 27 | TabController tabController; | 27 | TabController tabController; |
| 28 | - TextEditingController controller = TextEditingController(); | 28 | + |
| 29 | ContantShowModel contantShowModel; | 29 | ContantShowModel contantShowModel; |
| 30 | @override | 30 | @override |
| 31 | void initState() { | 31 | void initState() { |
| @@ -37,129 +37,145 @@ class _ContactListPageState extends State<ContactListPage> | @@ -37,129 +37,145 @@ class _ContactListPageState extends State<ContactListPage> | ||
| 37 | @override | 37 | @override |
| 38 | Widget build(BuildContext context) { | 38 | Widget build(BuildContext context) { |
| 39 | contantShowModel = Provider.of<ContantShowModel>(context, listen: true); | 39 | contantShowModel = Provider.of<ContantShowModel>(context, listen: true); |
| 40 | - return Scaffold( | ||
| 41 | - backgroundColor: MyColours.color_ffffff, | ||
| 42 | - appBar: SystemAppBar( | ||
| 43 | - '联系人', | ||
| 44 | - onTap: () { | ||
| 45 | - EventBus().emit('changeStatusColor'); | ||
| 46 | - Navigator.of(context).pop(); | ||
| 47 | - }, | ||
| 48 | - ), | ||
| 49 | - body: WillPopScope( | ||
| 50 | - child: SafeArea( | ||
| 51 | - child: Column( | ||
| 52 | - children: <Widget>[ | ||
| 53 | - Container( | ||
| 54 | - // color: Colors.red, | ||
| 55 | - padding: EdgeInsets.symmetric( | ||
| 56 | - horizontal: ScreenUtil().setWidth(40), | ||
| 57 | - vertical: ScreenUtil().setWidth(10)), | ||
| 58 | - height: ScreenUtil().setWidth(45 * 2), | ||
| 59 | - // alignment: Alignment.center, | ||
| 60 | - child: Container( | ||
| 61 | - alignment: Alignment.center, | ||
| 62 | - padding: EdgeInsets.symmetric( | ||
| 63 | - horizontal: ScreenUtil().setWidth(20 * 2), | ||
| 64 | - vertical: ScreenUtil().setWidth(14)), | ||
| 65 | - decoration: BoxDecoration( | ||
| 66 | - color: MyColours.color_F0F0F0, | ||
| 67 | - borderRadius: BorderRadius.circular( | ||
| 68 | - ScreenUtil().setWidth(24 * 2))), | ||
| 69 | - child: TextField( | ||
| 70 | - controller: controller, | ||
| 71 | - // focusNode: _focusNode, | ||
| 72 | - // autofocus: true, | 40 | + return Material( |
| 41 | + child: InkWell( | ||
| 42 | + onTap: () { | ||
| 43 | + FocusScope.of(context).requestFocus(FocusNode()); //点击空白处隐藏键盘 | ||
| 44 | + }, | ||
| 45 | + child: Scaffold( | ||
| 46 | + resizeToAvoidBottomInset: false, | ||
| 47 | + backgroundColor: MyColours.color_ffffff, | ||
| 48 | + appBar: SystemAppBar( | ||
| 49 | + '联系人', | ||
| 50 | + onTap: () { | ||
| 51 | + EventBus().emit('changeStatusColor'); | ||
| 52 | + Navigator.of(context).pop(); | ||
| 53 | + }, | ||
| 54 | + ), | ||
| 55 | + body: WillPopScope( | ||
| 56 | + child: SafeArea( | ||
| 57 | + child: Column( | ||
| 58 | + children: <Widget>[ | ||
| 59 | + Container( | ||
| 60 | + // color: Colors.red, | ||
| 61 | + padding: EdgeInsets.symmetric( | ||
| 62 | + horizontal: ScreenUtil().setWidth(40), | ||
| 63 | + vertical: ScreenUtil().setWidth(10)), | ||
| 64 | + height: ScreenUtil().setWidth(45 * 2), | ||
| 65 | + // alignment: Alignment.center, | ||
| 66 | + child: Container( | ||
| 67 | + alignment: Alignment.center, | ||
| 68 | + padding: EdgeInsets.symmetric( | ||
| 69 | + horizontal: ScreenUtil().setWidth(20 * 2), | ||
| 70 | + vertical: ScreenUtil().setWidth(14)), | ||
| 71 | + decoration: BoxDecoration( | ||
| 72 | + color: MyColours.color_F0F0F0, | ||
| 73 | + borderRadius: BorderRadius.circular( | ||
| 74 | + ScreenUtil().setWidth(24 * 2))), | ||
| 75 | + child: TextField( | ||
| 76 | + controller: contantShowModel.controller, | ||
| 77 | + // focusNode: _focusNode, | ||
| 78 | + // autofocus: true, | ||
| 73 | 79 | ||
| 74 | - style: TextStyle( | ||
| 75 | - color: MyColours.color_333333, | ||
| 76 | - fontSize: ScreenUtil().setSp(30), | ||
| 77 | - textBaseline: TextBaseline.alphabetic), | ||
| 78 | - textAlignVertical: TextAlignVertical.center, | ||
| 79 | - decoration: InputDecoration( | ||
| 80 | - hintText: "搜索联系人", | ||
| 81 | - hintStyle: TextStyle( | ||
| 82 | - color: MyColours.color_999999, | ||
| 83 | - fontSize: ScreenUtil().setSp(30), | ||
| 84 | - ), | ||
| 85 | - isCollapsed: | ||
| 86 | - true, //重点,相当于高度包裹的意思,必须设置为true,不然有默认奇妙的最小高度 | ||
| 87 | - border: InputBorder.none, | ||
| 88 | - //左边图标设置 | ||
| 89 | - icon: Image.asset( | ||
| 90 | - Utils.getImgPath('search'), | ||
| 91 | - width: ScreenUtil().setWidth(30), | ||
| 92 | - ), | ||
| 93 | - //右边图标设置 | ||
| 94 | - suffixIcon: GestureDetector( | ||
| 95 | - child: Container( | ||
| 96 | - height: ScreenUtil().setWidth(30), | ||
| 97 | - width: ScreenUtil().setWidth(30), | ||
| 98 | - alignment: Alignment.centerRight, | ||
| 99 | - child: Image.asset( | ||
| 100 | - Utils.getImgPath('clear'), | ||
| 101 | - width: ScreenUtil().setWidth(30), | ||
| 102 | - ), | 80 | + style: TextStyle( |
| 81 | + color: MyColours.color_333333, | ||
| 82 | + fontSize: ScreenUtil().setSp(30), | ||
| 83 | + textBaseline: TextBaseline.alphabetic), | ||
| 84 | + textAlignVertical: TextAlignVertical.center, | ||
| 85 | + decoration: InputDecoration( | ||
| 86 | + hintText: "搜索联系人", | ||
| 87 | + hintStyle: TextStyle( | ||
| 88 | + color: MyColours.color_999999, | ||
| 89 | + fontSize: ScreenUtil().setSp(30), | ||
| 90 | + ), | ||
| 91 | + isCollapsed: | ||
| 92 | + true, //重点,相当于高度包裹的意思,必须设置为true,不然有默认奇妙的最小高度 | ||
| 93 | + border: InputBorder.none, | ||
| 94 | + //左边图标设置 | ||
| 95 | + icon: Image.asset( | ||
| 96 | + Utils.getImgPath('search'), | ||
| 97 | + width: ScreenUtil().setWidth(30), | ||
| 98 | + ), | ||
| 99 | + //右边图标设置 | ||
| 100 | + suffixIcon: contantShowModel | ||
| 101 | + .controller.text == | ||
| 102 | + '' | ||
| 103 | + ? Container() | ||
| 104 | + : GestureDetector( | ||
| 105 | + child: Container( | ||
| 106 | + height: ScreenUtil().setWidth(30), | ||
| 107 | + width: ScreenUtil().setWidth(30), | ||
| 108 | + alignment: Alignment.centerRight, | ||
| 109 | + child: Image.asset( | ||
| 110 | + Utils.getImgPath('clear'), | ||
| 111 | + width: | ||
| 112 | + ScreenUtil().setWidth(30), | ||
| 113 | + ), | ||
| 114 | + ), | ||
| 115 | + onTap: () { | ||
| 116 | + WidgetsBinding.instance | ||
| 117 | + .addPostFrameCallback(((_) { | ||
| 118 | + contantShowModel.controller | ||
| 119 | + .clear(); | ||
| 120 | + contantShowModel.searchData(''); | ||
| 121 | + })); | ||
| 122 | + }, | ||
| 123 | + )), | ||
| 124 | + keyboardType: TextInputType.text, | ||
| 125 | + textInputAction: TextInputAction.search, | ||
| 126 | + onChanged: (value) { | ||
| 127 | + setState(() {}); | ||
| 128 | + // _searchSellerLocation(); | ||
| 129 | + contantShowModel.searchData(value); | ||
| 130 | + }, | ||
| 131 | + onEditingComplete: () { | ||
| 132 | + // _searchSellerLocation(); | ||
| 133 | + // _focusNode.unfocus(); | ||
| 134 | + }, | ||
| 103 | ), | 135 | ), |
| 104 | - onTap: () { | ||
| 105 | - WidgetsBinding.instance.addPostFrameCallback( | ||
| 106 | - ((_) => controller.clear())); | ||
| 107 | - }, | ||
| 108 | )), | 136 | )), |
| 109 | - keyboardType: TextInputType.text, | ||
| 110 | - textInputAction: TextInputAction.search, | ||
| 111 | - onChanged: (value) { | ||
| 112 | - setState(() {}); | ||
| 113 | - // _searchSellerLocation(); | ||
| 114 | - contantShowModel.searchData(value); | ||
| 115 | - }, | ||
| 116 | - onEditingComplete: () { | ||
| 117 | - // _searchSellerLocation(); | ||
| 118 | - // _focusNode.unfocus(); | ||
| 119 | - }, | ||
| 120 | - ), | 137 | + Container( |
| 138 | + padding: EdgeInsets.only( | ||
| 139 | + bottom: ScreenUtil().setWidth(10)), | ||
| 140 | + margin: EdgeInsets.symmetric( | ||
| 141 | + horizontal: ScreenUtil().setWidth(30)), | ||
| 142 | + child: TabBar( | ||
| 143 | + controller: tabController, | ||
| 144 | + indicator: CustomTabIndicator( | ||
| 145 | + radius: 0, | ||
| 146 | + ), | ||
| 147 | + indicatorColor: MyColours.color_199095, | ||
| 148 | + indicatorSize: TabBarIndicatorSize.tab, | ||
| 149 | + // indicatorPadding: EdgeInsets.symmetric( | ||
| 150 | + // horizontal: ScreenUtil().setWidth(12)), | ||
| 151 | + labelColor: MyColours.color_199095, | ||
| 152 | + labelStyle: TextStyle( | ||
| 153 | + fontSize: ScreenUtil().setSp(32), | ||
| 154 | + fontWeight: FontWeight.bold), | ||
| 155 | + labelPadding: EdgeInsets.zero, | ||
| 156 | + unselectedLabelStyle: | ||
| 157 | + TextStyle(fontWeight: FontWeight.normal), | ||
| 158 | + unselectedLabelColor: MyColours.color_999999, | ||
| 159 | + tabs: _tabBarTitle.map((value) { | ||
| 160 | + return Tab( | ||
| 161 | + child: Text(value), | ||
| 162 | + ); | ||
| 163 | + }).toList()), | ||
| 164 | + ), | ||
| 165 | + Expanded( | ||
| 166 | + child: TabBarView( | ||
| 167 | + controller: tabController, | ||
| 168 | + // physics: NeverScrollableScrollPhysics(), | ||
| 169 | + children: <Widget>[ | ||
| 170 | + ContantLeftPage(), | ||
| 171 | + ContantRightPage(), | ||
| 172 | + ], | ||
| 173 | + )), | ||
| 174 | + ], | ||
| 121 | )), | 175 | )), |
| 122 | - Container( | ||
| 123 | - padding: EdgeInsets.only(bottom: ScreenUtil().setWidth(10)), | ||
| 124 | - margin: EdgeInsets.symmetric( | ||
| 125 | - horizontal: ScreenUtil().setWidth(30)), | ||
| 126 | - child: TabBar( | ||
| 127 | - controller: tabController, | ||
| 128 | - indicator: CustomTabIndicator( | ||
| 129 | - radius: 0, | ||
| 130 | - ), | ||
| 131 | - indicatorColor: MyColours.color_199095, | ||
| 132 | - indicatorSize: TabBarIndicatorSize.tab, | ||
| 133 | - // indicatorPadding: EdgeInsets.symmetric( | ||
| 134 | - // horizontal: ScreenUtil().setWidth(12)), | ||
| 135 | - labelColor: MyColours.color_199095, | ||
| 136 | - labelStyle: TextStyle( | ||
| 137 | - fontSize: ScreenUtil().setSp(32), | ||
| 138 | - fontWeight: FontWeight.bold), | ||
| 139 | - labelPadding: EdgeInsets.zero, | ||
| 140 | - unselectedLabelStyle: | ||
| 141 | - TextStyle(fontWeight: FontWeight.normal), | ||
| 142 | - unselectedLabelColor: MyColours.color_999999, | ||
| 143 | - tabs: _tabBarTitle.map((value) { | ||
| 144 | - return Tab( | ||
| 145 | - child: Text(value), | ||
| 146 | - ); | ||
| 147 | - }).toList()), | ||
| 148 | - ), | ||
| 149 | - Expanded( | ||
| 150 | - child: TabBarView( | ||
| 151 | - controller: tabController, | ||
| 152 | - // physics: NeverScrollableScrollPhysics(), | ||
| 153 | - children: <Widget>[ | ||
| 154 | - ContantLeftPage(), | ||
| 155 | - ContantRightPage(), | ||
| 156 | - ], | ||
| 157 | - )), | ||
| 158 | - ], | ||
| 159 | - )), | ||
| 160 | - onWillPop: () async { | ||
| 161 | - EventBus().emit('changeStatusColor'); | ||
| 162 | - return true; | ||
| 163 | - })); | 176 | + onWillPop: () async { |
| 177 | + EventBus().emit('changeStatusColor'); | ||
| 178 | + return true; | ||
| 179 | + })))); | ||
| 164 | } | 180 | } |
| 165 | } | 181 | } |
| @@ -128,6 +128,7 @@ class _ContantRightPageState extends State<ContantRightPage> { | @@ -128,6 +128,7 @@ class _ContantRightPageState extends State<ContantRightPage> { | ||
| 128 | setState(() { | 128 | setState(() { |
| 129 | _contacts = contacts; | 129 | _contacts = contacts; |
| 130 | if (_contacts.length > 0) { | 130 | if (_contacts.length > 0) { |
| 131 | + contantShowModel.contacts = []; | ||
| 131 | for (int i = 0; i < _contacts.length; i++) { | 132 | for (int i = 0; i < _contacts.length; i++) { |
| 132 | UserHistoryEntity item = UserHistoryEntity( | 133 | UserHistoryEntity item = UserHistoryEntity( |
| 133 | '', | 134 | '', |
| @@ -136,8 +137,19 @@ class _ContantRightPageState extends State<ContantRightPage> { | @@ -136,8 +137,19 @@ class _ContantRightPageState extends State<ContantRightPage> { | ||
| 136 | '', | 137 | '', |
| 137 | _contacts[i].phones.first.value, | 138 | _contacts[i].phones.first.value, |
| 138 | ''); | 139 | ''); |
| 139 | - item.pinyin = | ||
| 140 | - item.pinyin = PinyinHelper.getPinyin(_contacts[i].displayName); | 140 | + item.pinyin = PinyinHelper.getPinyin(_contacts[i].displayName) |
| 141 | + .replaceAll(' ', ''); | ||
| 142 | + item.pinyinList = | ||
| 143 | + PinyinHelper.getPinyin(_contacts[i].displayName).split(' '); | ||
| 144 | + item.pinyinFirst = ''; | ||
| 145 | + for (int j = 0; j < item.pinyinList.length; j++) { | ||
| 146 | + String letter = item.pinyinList[j]; | ||
| 147 | + if (letter.length > 0) { | ||
| 148 | + item.pinyinFirst += item.pinyinList[j].substring(0, 1); | ||
| 149 | + } else { | ||
| 150 | + item.pinyinFirst += ''; | ||
| 151 | + } | ||
| 152 | + } | ||
| 141 | contantShowModel.contacts.add(item); | 153 | contantShowModel.contacts.add(item); |
| 142 | } | 154 | } |
| 143 | contantShowModel.contactsShow = contantShowModel.contacts; | 155 | contantShowModel.contactsShow = contantShowModel.contacts; |
| @@ -16,6 +16,7 @@ class ContantShowModel extends ChangeNotifier { | @@ -16,6 +16,7 @@ class ContantShowModel extends ChangeNotifier { | ||
| 16 | List<UserHistoryEntity> contacts = []; //手机通讯录(总) | 16 | List<UserHistoryEntity> contacts = []; //手机通讯录(总) |
| 17 | List<UserHistoryEntity> userHistorysShow = []; //历史录入展示 | 17 | List<UserHistoryEntity> userHistorysShow = []; //历史录入展示 |
| 18 | List<UserHistoryEntity> contactsShow = []; //手机通讯录展示 | 18 | List<UserHistoryEntity> contactsShow = []; //手机通讯录展示 |
| 19 | + TextEditingController controller = TextEditingController(); //搜索框 | ||
| 19 | 20 | ||
| 20 | //获取历史录入 | 21 | //获取历史录入 |
| 21 | getUserHistorys(BuildContext context, Map<String, String> params) async { | 22 | getUserHistorys(BuildContext context, Map<String, String> params) async { |
| @@ -48,7 +49,17 @@ class ContantShowModel extends ChangeNotifier { | @@ -48,7 +49,17 @@ class ContantShowModel extends ChangeNotifier { | ||
| 48 | } else { | 49 | } else { |
| 49 | for (int i = 0; i < userHistorys.length; i++) { | 50 | for (int i = 0; i < userHistorys.length; i++) { |
| 50 | UserHistoryEntity item = userHistorys[i]; | 51 | UserHistoryEntity item = userHistorys[i]; |
| 51 | - item.pinyin = PinyinHelper.getPinyin(item.rname); | 52 | + item.pinyin = PinyinHelper.getPinyin(item.rname).replaceAll(' ', ''); |
| 53 | + item.pinyinList = PinyinHelper.getPinyin(item.rname).split(' '); | ||
| 54 | + item.pinyinFirst = ''; | ||
| 55 | + for (int j = 0; j < item.pinyinList.length; j++) { | ||
| 56 | + String letter = item.pinyinList[j]; | ||
| 57 | + if (letter.length > 0) { | ||
| 58 | + item.pinyinFirst += item.pinyinList[j].substring(0, 1); | ||
| 59 | + } else { | ||
| 60 | + item.pinyinFirst += ''; | ||
| 61 | + } | ||
| 62 | + } | ||
| 52 | userHistorys[i] = item; | 63 | userHistorys[i] = item; |
| 53 | } | 64 | } |
| 54 | userHistorysShow = userHistorys; | 65 | userHistorysShow = userHistorys; |
| @@ -59,31 +70,50 @@ class ContantShowModel extends ChangeNotifier { | @@ -59,31 +70,50 @@ class ContantShowModel extends ChangeNotifier { | ||
| 59 | } | 70 | } |
| 60 | 71 | ||
| 61 | searchData(String key) { | 72 | searchData(String key) { |
| 62 | - userHistorysShow = []; | ||
| 63 | - contactsShow = []; | ||
| 64 | - // for (int i = 0; i < userHistorys.length; i++) { | ||
| 65 | - | ||
| 66 | - // String name = userHistorys[i].rname; | ||
| 67 | - // String pinyin = userHistorys[i].pinyin; | ||
| 68 | - // String phone = userHistorys[i].phone; | ||
| 69 | - // if (name.contains(key) || pinyin.contains(key) || phone.contains(key)) { | ||
| 70 | - // userHistorysShow.add(userHistorys[i]); | ||
| 71 | - // } | ||
| 72 | - // } | ||
| 73 | - for (int i = 0; i < contacts.length; i++) { | ||
| 74 | - String name = contacts[i].rname; | ||
| 75 | - String pinyin = contacts[i].pinyin; | ||
| 76 | - String phone = contacts[i].phone; | ||
| 77 | - if (name.contains(key) || pinyin.contains(key) || phone.contains(key)) { | ||
| 78 | - contactsShow.add(contacts[i]); | 73 | + if (key == '') { |
| 74 | + userHistorysShow = userHistorys; | ||
| 75 | + contactsShow = contacts; | ||
| 76 | + pageStateRight = PageState.Success; | ||
| 77 | + pageStateLeft = PageState.Success; | ||
| 78 | + } else { | ||
| 79 | + userHistorysShow = []; | ||
| 80 | + contactsShow = []; | ||
| 81 | + for (int i = 0; i < userHistorys.length; i++) { | ||
| 82 | + String name = userHistorys[i].rname; | ||
| 83 | + String pinyinFirst = userHistorys[i].pinyinFirst; | ||
| 84 | + List<String> pinyinList = userHistorys[i].pinyinList; | ||
| 85 | + String phone = userHistorys[i].phone; | ||
| 86 | + if (name.contains(key) || | ||
| 87 | + pinyinFirst.contains(key) || | ||
| 88 | + phone.contains(key) || | ||
| 89 | + pinyinList.contains(key)) { | ||
| 90 | + userHistorysShow.add(userHistorys[i]); | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + for (int i = 0; i < contacts.length; i++) { | ||
| 94 | + String name = contacts[i].rname; | ||
| 95 | + String pinyinFirst = contacts[i].pinyinFirst; | ||
| 96 | + List<String> pinyinList = contacts[i].pinyinList; | ||
| 97 | + String phone = contacts[i].phone; | ||
| 98 | + if (name.contains(key) || | ||
| 99 | + pinyinFirst.contains(key) || | ||
| 100 | + phone.contains(key) || | ||
| 101 | + pinyinList.contains(key)) { | ||
| 102 | + contactsShow.add(contacts[i]); | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | + if (userHistorysShow.length == 0) { | ||
| 106 | + pageStateLeft = PageState.Empty; | ||
| 107 | + } else { | ||
| 108 | + pageStateLeft = PageState.Success; | ||
| 109 | + } | ||
| 110 | + if (contactsShow.length == 0) { | ||
| 111 | + pageStateRight = PageState.Empty; | ||
| 112 | + } else { | ||
| 113 | + pageStateRight = PageState.Success; | ||
| 79 | } | 114 | } |
| 80 | } | 115 | } |
| 81 | - if (userHistorysShow.length == 0) { | ||
| 82 | - pageStateLeft = PageState.Empty; | ||
| 83 | - } | ||
| 84 | - if (contactsShow.length == 0) { | ||
| 85 | - pageStateRight = PageState.Empty; | ||
| 86 | - } | 116 | + |
| 87 | notifyListeners(); | 117 | notifyListeners(); |
| 88 | } | 118 | } |
| 89 | } | 119 | } |
| 1 | +import 'dart:convert'; | ||
| 1 | import 'dart:io'; | 2 | import 'dart:io'; |
| 2 | import 'dart:math'; | 3 | import 'dart:math'; |
| 3 | import 'dart:typed_data'; | 4 | import 'dart:typed_data'; |
| @@ -28,6 +29,28 @@ import '../app.dart'; | @@ -28,6 +29,28 @@ import '../app.dart'; | ||
| 28 | typedef BookTimeSetCallback = void Function(bool needChange); | 29 | typedef BookTimeSetCallback = void Function(bool needChange); |
| 29 | 30 | ||
| 30 | class Utils { | 31 | class Utils { |
| 32 | + static List<String> stringToList(String str) { | ||
| 33 | + List<String> list = <String>[]; | ||
| 34 | + // for (var value in JsonDecoder().convert(str)) { | ||
| 35 | + // list.add(value); | ||
| 36 | + // } | ||
| 37 | + list = jsonDecode(str); | ||
| 38 | + return list; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | + // 正则验证 | ||
| 42 | + static bool isChinese(String value) { | ||
| 43 | + return RegExp(r"[\u4e00-\u9fa5]").hasMatch(value); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + static bool isNum(String value) { | ||
| 47 | + return RegExp(r'^[0-9]*$').hasMatch(value); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + static bool isPinyin(String value) { | ||
| 51 | + return RegExp(r'^[A-Za-z]+$').hasMatch(value); | ||
| 52 | + } | ||
| 53 | + | ||
| 31 | /** | 54 | /** |
| 32 | * 获取图片后缀 | 55 | * 获取图片后缀 |
| 33 | * | 56 | * |
-
Please register or login to post a comment