import 'package:clean/base/base_page.dart'; import 'package:clean/module/contact/all/all_controller.dart'; import 'package:clean/module/contact/contact_state.dart'; import 'package:clean/resource/assets.gen.dart'; import 'package:clean/utils/expand.dart'; import 'package:flutter/Material.dart'; import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; class AllPage extends BasePage { const AllPage({super.key}); @override bool immersive() { return true; } @override bool statusBarDarkFont() => false; @override Widget buildBody(BuildContext context) { return Stack( children: [ buildMain(context), IgnorePointer( child: Assets.images.bgHome.image( width: 360.w, ), ), ], ); } Widget buildMain(BuildContext context) { return SafeArea( child: Container( padding: EdgeInsets.only(left: 16.w, top: 14.h, right: 16.w), child: Obx(() { return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ !controller.isEdit.value ? Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { Get.back(); }, child: Assets.images.iconCommonBack .image(width: 28.w, height: 28.w), ), GestureDetector( onTap: () { controller.isEdit.value = true; }, child: Container( width: 71.w, height: 30.h, decoration: BoxDecoration( color: "#1F2D3F".color, borderRadius: BorderRadius.all( Radius.circular(15.h), ), ), child: Center( child: Text( "Select", style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ), ], ) : Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ GestureDetector( onTap: () { controller.isEdit.value = false; }, child: Container( width: 71.w, height: 30.h, decoration: BoxDecoration( color: "#1F2D3F".color, borderRadius: BorderRadius.all( Radius.circular(15.h), ), ), child: Center( child: Text( "Cancel", style: TextStyle( color: Colors.white, fontSize: 14.sp, ), ), ), ), ), GestureDetector( onTap: () { controller.toggleSelectAll(); }, child: Text( controller.isAllSelected.value ? "Deselect all" : "Select All", style: TextStyle( color: Colors.white.withOpacity(0.65), fontSize: 14.sp, ), ), ), ], ), SizedBox( height: 12.h, ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "All Contacts", style: TextStyle( color: Colors.white, fontWeight: FontWeight.w700, fontSize: 24.sp, ), ), ], ), Expanded( child: Row( children: [ Expanded( child: Obx(() { return ScrollablePositionedList.builder( itemCount: ContactState.initials.length, itemScrollController: controller.itemScrollController, itemPositionsListener: controller.itemPositionsListener, itemBuilder: (context, index) { String initial = ContactState.initials[index]; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( height: 12.h, ), Padding( padding: EdgeInsets.symmetric(vertical: 8.h), child: Text( initial, style: TextStyle( color: Colors.white.withOpacity(0.7), fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), ), ...ContactState.groupedContacts[initial]! .asMap() .entries .map((entry) { int index = entry.key; // 当前联系人的索引 Contact contact = entry.value; // 当前联系人 bool isFirst = index == 0; // 是否是第一个 bool isLast = index == (ContactState.groupedContacts[initial] ?.length ?? 0) - 1; // 是否是最后一个 return Container( padding: EdgeInsets.only( left: 10.w, top: 10.h, right: 10.w, ), width: double.infinity, // height: 62.h, decoration: BoxDecoration( borderRadius: BorderRadius.vertical( top: isFirst ? Radius.circular(12) : Radius.zero, // 第一个设置上圆角 bottom: isLast ? Radius.circular(12) : Radius.zero, // 最后一个设置下圆角 ), color: Colors.white.withOpacity(0.12), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( contact.displayName.isEmpty ? 'No contact name' : contact.displayName, style: TextStyle( color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), SizedBox( height: 5.h, ), Text( contact.phones.isEmpty ? 'No contact number' : contact.phones.first .number, style: TextStyle( color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), ], ), // 删除按钮 Visibility( visible: controller.isEdit.value, child: GestureDetector( onTap: () { controller .toggleSelectContact( contact); }, child: Container( child: controller .selectedContacts .contains( contact.id) ? Center( child: Assets.images .iconSelected .image( width: 20.w, height: 20.h, ), ) : Center( child: Assets.images .iconUnselected .image( width: 20.w, height: 20.h, ), ), ), ), ), ], ), SizedBox( height: 10.h, ), Visibility( visible: !isLast, child: Container( height: 1.h, color: "#3E3E47".color, )), ], )); }), SizedBox( height: 12.h, ), ], ); }, ); }), ), Container( width: 30, child: ListView.builder( // physics: NeverScrollableScrollPhysics(), itemCount: ContactState.initials.length, itemBuilder: (context, index) { return GestureDetector( onTap: () => controller .scrollToInitial(ContactState.initials[index]), child: Padding( padding: EdgeInsets.symmetric(vertical: 2), child: Text( ContactState.initials[index], textAlign: TextAlign.center, style: TextStyle( fontSize: 14, color: "#0279FB".color, fontWeight: FontWeight.bold, ), ), ), ); }, ), ), ], ), ), Visibility( visible: controller.isEdit.value, child: GestureDetector( onTap: () { controller.deleteBtnClick(); }, child: Container( width: 328.w, height: 48.h, decoration: BoxDecoration( color: "#0279FB".color, borderRadius: BorderRadius.all( Radius.circular(10.r), ), ), child: Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( "Delete", style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ], ), ), ), ), ) ], ); }), ), ); } }