Commit 5bc6495f5c4e1a8db9487cb65d6ff93a46979887

Authored by wdn127929
1 parent 80cd9bc6

联系人

... ... @@ -6,6 +6,7 @@ enum PageState{
ConnectivityTimeOut,//请求超时
ConnectivityError,//请求错误
Empty,//空页面
NoPermission,//没有权限
First,
Success//成功
}
... ...
... ... @@ -5,6 +5,7 @@ import 'package:one_key/constant/state.dart';
import 'package:one_key/provider/contant_show_model.dart';
import 'package:one_key/provider/user_model.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/widgets/MyDivider.dart';
import 'package:one_key/widgets/page_exception.dart';
import 'package:one_key/widgets/v_empty_view.dart';
... ... @@ -41,66 +42,80 @@ class _ContantLeftPageState extends State<ContantLeftPage> {
@override
Widget build(BuildContext context) {
contantShowModel = Provider.of<ContantShowModel>(context, listen: true);
return Expanded(
child: Consumer<ContantShowModel>(
builder: (context, model, _) {
if (model.pageStateLeft != PageState.Success) {
return ExceptionPage(
pageState: model.pageStateLeft,
callback: () {
// offset = 0;
// getMessages();
_getContantData();
},
emptyMsg: "暂时没有联系人哦",
emptyImg: "empty_search",
showMsg: "加载中,请稍后...",
);
} else {
return EasyRefresh.custom(
controller: _controller,
slivers: [
SliverList(delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(40),
vertical: ScreenUtil().setWidth(30)),
height: ScreenUtil().setWidth(74 * 2),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: ScreenUtil().setWidth(2),
color: MyColours.color_E0E0E0))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(model.userHistorys[index].rname,
style: TextStyle(
color: MyColours.color_333333,
fontSize: ScreenUtil().setSp(32))),
VEmptyView(10),
Text(model.userHistorys[index].phone,
style: TextStyle(
color: MyColours.color_999999,
fontSize: ScreenUtil().setSp(30)))
],
),
);
}))
],
// onRefresh: () async {
// // offset = 0;
// // getMessages(showLoading: false);
// },
// onLoad: () async {
// // offset++;
// // getMessages(showLoading: false);
// },
);
}
},
),
return Consumer<ContantShowModel>(
builder: (context, model, _) {
if (model.pageStateLeft != PageState.Success) {
return ExceptionPage(
pageState: model.pageStateLeft,
callback: () {
// offset = 0;
// getMessages();
_getContantData();
},
emptyMsg: "暂时没有联系人哦",
emptyImg: "empty_search",
showMsg: "加载中,请稍后...",
);
} else {
return ListView.builder(
itemCount: model.userHistorys.length,
itemBuilder: (BuildContext context, int index) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
index == 0
? MyDivider(
double.infinity,
ScreenUtil().setWidth(20),
color: MyColours.color_f5f5f5,
)
: Container(),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(40),
vertical: ScreenUtil().setWidth(30)),
height: ScreenUtil().setWidth(74 * 2),
decoration: BoxDecoration(
border: Border(
top: index == 0
? BorderSide(
width: ScreenUtil().setWidth(2),
color: MyColours.color_E0E0E0)
: BorderSide(
width: 0, color: Colors.transparent),
bottom: BorderSide(
width: ScreenUtil().setWidth(2),
color: MyColours.color_E0E0E0))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(model.userHistorys[index].rname,
style: TextStyle(
color: MyColours.color_333333,
fontSize: ScreenUtil().setSp(32))),
VEmptyView(10),
Text(model.userHistorys[index].phone,
style: TextStyle(
color: MyColours.color_999999,
fontSize: ScreenUtil().setSp(30)))
],
),
)
]);
});
// onRefresh: () async {
// // offset = 0;
// // getMessages(showLoading: false);
// },
// onLoad: () async {
// // offset++;
// // getMessages(showLoading: false);
// },
}
},
);
}
}
... ...
... ... @@ -5,10 +5,17 @@ import 'package:contacts_service/contacts_service.dart';
import 'package:flutter_screenutil/screenutil.dart';
import 'package:intl/intl.dart';
import 'package:one_key/pages/my/contant_left_page.dart';
import 'package:one_key/pages/my/contant_right_page.dart';
import 'package:one_key/provider/contant_show_model.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/dialog_util.dart';
import 'package:one_key/utils/event_bus.dart';
import 'package:one_key/utils/misc.dart';
import 'package:one_key/widgets/MyDivider.dart';
import 'package:one_key/widgets/custom_tab_indicator.dart';
import 'package:one_key/widgets/system_app_bar.dart';
import 'package:one_key/widgets/v_empty_view.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:provider/provider.dart';
class ContactListPage extends StatefulWidget {
... ... @@ -16,111 +23,77 @@ class ContactListPage extends StatefulWidget {
_ContactListPageState createState() => _ContactListPageState();
}
class _ContactListPageState extends State<ContactListPage> {
class _ContactListPageState extends State<ContactListPage>
with TickerProviderStateMixin {
List<Contact> _contacts;
List _tabBarTitle;
TabController tabController;
@override
void initState() {
_tabBarTitle = ['预订联系人', '手机联系人'];
super.initState();
refreshContacts();
}
Future<void> refreshContacts() async {
// Load without thumbnails initially.
var contacts = (await ContactsService.getContacts(
withThumbnails: false, iOSLocalizedLabels: false))
.toList();
// var contacts = (await ContactsService.getContactsForPhone("8554964652"))
// .toList();
setState(() {
_contacts = contacts;
});
// Lazy load thumbnails after rendering initial contacts.
for (final contact in contacts) {
ContactsService.getAvatar(contact).then((avatar) {
if (avatar == null) return; // Don't redraw if no change.
setState(() => contact.avatar = avatar);
});
}
}
void updateContact() async {
Contact ninja = _contacts
.toList()
.firstWhere((contact) => contact.familyName.startsWith("Ninja"));
ninja.avatar = null;
await ContactsService.updateContact(ninja);
refreshContacts();
}
_openContactForm() async {
try {
var contact =
await ContactsService.openContactForm(iOSLocalizedLabels: false);
refreshContacts();
} on FormOperationException catch (e) {
switch (e.errorCode) {
case FormOperationErrorCode.FORM_OPERATION_CANCELED:
case FormOperationErrorCode.FORM_COULD_NOT_BE_OPEN:
case FormOperationErrorCode.FORM_OPERATION_UNKNOWN_ERROR:
default:
print(e.errorCode);
}
}
tabController = TabController(length: 2, vsync: this);
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: MyColours.color_ffffff,
appBar: SystemAppBar('联系人'),
body: SafeArea(
child: DefaultTabController(
length: 2,
child: Stack(
appBar: SystemAppBar(
'联系人',
onTap: () {
EventBus().emit('changeStatusColor');
Navigator.of(context).pop();
},
),
body: WillPopScope(
child: SafeArea(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.only(bottom: ScreenUtil().setWidth(10)),
margin: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(30)),
child: TabBar(
controller: tabController,
indicator: CustomTabIndicator(
radius: 0,
),
indicatorColor: MyColours.color_199095,
indicatorSize: TabBarIndicatorSize.tab,
// indicatorPadding: EdgeInsets.symmetric(
// horizontal: ScreenUtil().setWidth(12)),
labelColor: MyColours.color_199095,
labelStyle: TextStyle(
fontSize: ScreenUtil().setSp(32),
fontWeight: FontWeight.bold),
labelPadding: EdgeInsets.zero,
unselectedLabelStyle:
TextStyle(fontWeight: FontWeight.normal),
unselectedLabelColor: MyColours.color_999999,
tabs: _tabBarTitle.map((value) {
return Tab(
child: Text(value),
);
}).toList()),
),
Expanded(
child: TabBarView(
controller: tabController,
// physics: NeverScrollableScrollPhysics(),
children: <Widget>[
TabBarView(
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
ChangeNotifierProvider<ContantShowModel>(
create: (_) => ContantShowModel(),
child: ContantLeftPage()),
Container()
],
),
Positioned(
child: Container(
padding:
EdgeInsets.only(bottom: ScreenUtil().setWidth(10)),
margin: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(30)),
child: TabBar(
indicator: CustomTabIndicator(
radius: 0,
),
indicatorColor: MyColours.color_199095,
indicatorSize: TabBarIndicatorSize.tab,
// indicatorPadding: EdgeInsets.symmetric(
// horizontal: ScreenUtil().setWidth(12)),
labelColor: MyColours.color_199095,
labelStyle: TextStyle(
fontSize: ScreenUtil().setSp(32),
fontWeight: FontWeight.bold),
labelPadding: EdgeInsets.zero,
unselectedLabelStyle:
TextStyle(fontWeight: FontWeight.normal),
unselectedLabelColor: MyColours.color_999999,
tabs: _tabBarTitle.map((value) {
return Tab(
child: Text(value),
);
}).toList()),
))
ChangeNotifierProvider<ContantShowModel>(
create: (_) => ContantShowModel(),
child: ContantLeftPage()),
ContantRightPage()
],
))));
)),
],
)),
onWillPop: () async {
EventBus().emit('changeStatusColor');
return true;
}));
}
}
... ...
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:one_key/constant/state.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/utils/dialog_util.dart';
import 'package:one_key/utils/misc.dart';
import 'package:one_key/widgets/MyDivider.dart';
import 'package:one_key/widgets/page_exception.dart';
import 'package:one_key/widgets/v_empty_view.dart';
import 'package:contacts_service/contacts_service.dart';
import 'package:permission_handler/permission_handler.dart';
class ContantRightPage extends StatefulWidget {
ContantRightPage({Key key}) : super(key: key);
@override
_ContantRightPageState createState() => _ContantRightPageState();
}
class _ContantRightPageState extends State<ContantRightPage> {
PageState _pageState = PageState.Loading;
List<Contact> _contacts;
bool isNeed = false;
bool goSetting = false;
bool userNo = false;
@override
void initState() {
super.initState();
_openAddressBook();
}
// Future<void> _askPermissions() async {
// PermissionStatus permissionStatus = await _getContactPermission();
// if (permissionStatus != PermissionStatus.granted) {
// _handleInvalidPermissions(permissionStatus);
// }
// }
_openAddressBook() async {
if (!(await checkContactPermission())) {
PermissionStatus permissionStatus = await contactPermissionStatus();
if (permissionStatus == PermissionStatus.permanentlyDenied) {
//用户选择不在弹出权限提示框
print('never');
userNo = true;
setState(() {
_pageState = PageState.NoPermission;
});
// DialogUtil.openAlertDialog(
// context, '未获得通讯录权限', "请在手机的权限管理里,将通讯录权限开启", '去设置', 340.0,
// onTap: () {
// goSetting = true;
// openSetting();
// Navigator.pop(context, '');
// });
} else {
// 申请权限
bool canContacts = await requestContactPermission();
if (canContacts) {
refreshContacts();
} else {
setState(() {
_pageState = PageState.NoPermission;
});
//拒绝通讯录权限 , 苹果拒绝权限后,不再提示权限框,进入此处
// DialogUtil.openAlertDialog(
// context, '未获得通讯录权限', "请在手机的权限管理里,将通讯录权限开启。", '去设置', 340.0,
// onTap: () {
// goSetting = true;
// openSetting();
// Navigator.pop(context, '');
// });
}
}
} else {
refreshContacts();
}
}
// Future<PermissionStatus> _getContactPermission() async {
// PermissionStatus permission = await PermissionHandler()
// .checkPermissionStatus(PermissionGroup.contacts);
// if (permission != PermissionStatus.granted &&
// permission != PermissionStatus.disabled) {
// Map<PermissionGroup, PermissionStatus> permissionStatus =
// await PermissionHandler()
// .requestPermissions([PermissionGroup.contacts]);
// return permissionStatus[PermissionGroup.contacts] ??
// PermissionStatus.unknown;
// } else {
// return permission;
// }
// }
// void _handleInvalidPermissions(PermissionStatus permissionStatus) {
// if (permissionStatus == PermissionStatus.denied) {
// throw PlatformException(
// code: "PERMISSION_DENIED",
// message: "Access to location data denied",
// details: null);
// } else if (permissionStatus == PermissionStatus.disabled) {
// throw PlatformException(
// code: "PERMISSION_DISABLED",
// message: "Location data is not available on device",
// details: null);
// }
// }
Future<void> refreshContacts() async {
// Load without thumbnails initially.
var contacts = (await ContactsService.getContacts(
withThumbnails: false, iOSLocalizedLabels: false))
.toList();
// var contacts = (await ContactsService.getContactsForPhone("8554964652"))
// .toList();
setState(() {
_contacts = contacts;
if (_contacts.length > 0) {
_pageState = PageState.Success;
} else {
_pageState = PageState.Empty;
}
});
// Lazy load thumbnails after rendering initial contacts.
for (final contact in contacts) {
ContactsService.getAvatar(contact).then((avatar) {
if (avatar == null) return; // Don't redraw if no change.
setState(() => contact.avatar = avatar);
});
}
}
void updateContact() async {
Contact ninja = _contacts
.toList()
.firstWhere((contact) => contact.familyName.startsWith("Ninja"));
ninja.avatar = null;
await ContactsService.updateContact(ninja);
refreshContacts();
}
_openContactForm() async {
try {
var contact =
await ContactsService.openContactForm(iOSLocalizedLabels: false);
refreshContacts();
} on FormOperationException catch (e) {
switch (e.errorCode) {
case FormOperationErrorCode.FORM_OPERATION_CANCELED:
case FormOperationErrorCode.FORM_COULD_NOT_BE_OPEN:
case FormOperationErrorCode.FORM_OPERATION_UNKNOWN_ERROR:
default:
print(e.errorCode);
}
}
}
// /// app生命周期
// @override
// void didChangeAppLifecycleState(AppLifecycleState state) async {
// switch (state) {
// case AppLifecycleState.resumed: // 应用程序可见,前台
// if (!Platform.isAndroid) {
// if (isNeed) {
// isNeed = false;
// if (goSetting) {
// _getContactPemisoin();
// }
// }
// } else {
// if (goSetting) {
// _getContactPemisoin();
// }
// }
// break;
// case AppLifecycleState.paused:
// print('paused');
// // if (!Platform.isAndroid) {
// // if (!(await checkLocationPermission())) {
// // //没有定位权限
// isNeed = true;
// // } else {
// // isNeed = false;
// // }
// // }
// break;
// default:
// break;
// }
// }
/// 程序进入前台刷新位置权限(来回切换位置权限,及时刷新页面)
_getContactPemisoin() async {
if (await checkContactPermission()) {
userNo = false;
}
if (!userNo) {
goSetting = false;
_openAddressBook();
}
}
@override
Widget build(BuildContext context) {
return _pageState != PageState.Success
? ExceptionPage(
pageState: _pageState,
callback: () async {
if (await checkContactPermission()) {
_openAddressBook();
} else {
goSetting = true;
openSetting();
}
;
},
emptyMsg: "暂时没有联系人哦",
emptyImg: "empty_search",
showMsg: "加载中,请稍后...",
)
: ListView.builder(
itemCount: _contacts?.length ?? 0,
itemBuilder: (BuildContext context, int index) {
Contact c = _contacts?.elementAt(index);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
index == 0
? MyDivider(
double.infinity,
ScreenUtil().setWidth(20),
color: MyColours.color_f5f5f5,
)
: Container(),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(
horizontal: ScreenUtil().setWidth(40),
vertical: ScreenUtil().setWidth(30)),
height: ScreenUtil().setWidth(74 * 2),
decoration: BoxDecoration(
border: Border(
top: index == 0
? BorderSide(
width: ScreenUtil().setWidth(2),
color: MyColours.color_E0E0E0)
: BorderSide(
width: 0, color: Colors.transparent),
bottom: BorderSide(
width: ScreenUtil().setWidth(2),
color: MyColours.color_E0E0E0))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(c.displayName,
style: TextStyle(
color: MyColours.color_333333,
fontSize: ScreenUtil().setSp(32))),
VEmptyView(10),
Text(c.phones.first.value,
style: TextStyle(
color: MyColours.color_999999,
fontSize: ScreenUtil().setSp(30)))
],
),
)
]);
});
}
}
... ...
... ... @@ -3,54 +3,73 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:one_key/res/colors.dart';
import 'package:one_key/widgets/v_empty_view.dart';
class ErrorPage extends StatefulWidget{
class ErrorPage extends StatefulWidget {
final String content;
final String btnTitle;
final VoidCallback callback;
const ErrorPage({Key key, this.callback,this.content="哎呀~网络好像走失了呢"}) : super(key: key);
const ErrorPage(
{Key key,
this.callback,
this.content = "哎呀~网络好像走失了呢",
this.btnTitle = '点击刷新'})
: super(key: key);
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return new ErrorPageState();
}
}
class ErrorPageState extends State<ErrorPage>{
class ErrorPageState extends State<ErrorPage> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Container(
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
VEmptyView(120),
Image.asset("assets/bg_error.png",width: ScreenUtil().setWidth(520),height: ScreenUtil().setWidth(384),),
VEmptyView(40),
Text("${widget.content}",style: TextStyle(fontSize: ScreenUtil().setSp(28),color: MyColours.color_353535),),
VEmptyView(20),
widget.callback!=null?GestureDetector(
onTap: widget.callback,
child: Container(
width: ScreenUtil().setWidth(152),
height: ScreenUtil().setWidth(58),
decoration: BoxDecoration(
color: MyColours.app_main,
borderRadius: BorderRadius.all(Radius.circular(ScreenUtil().setWidth(28)))
),
child: Center(
child: Text("点击刷新",style: TextStyle(fontSize: ScreenUtil().setSp(28),color: MyColours.color_ffffff),),
),
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
VEmptyView(120),
Image.asset(
"assets/bg_error.png",
width: ScreenUtil().setWidth(520),
height: ScreenUtil().setWidth(384),
),
VEmptyView(40),
Text(
"${widget.content}",
style: TextStyle(
fontSize: ScreenUtil().setSp(28),
color: MyColours.color_353535),
),
):Container()
],
)
);
VEmptyView(20),
widget.callback != null
? GestureDetector(
onTap: widget.callback,
child: Container(
width: ScreenUtil().setWidth(152),
height: ScreenUtil().setWidth(58),
decoration: BoxDecoration(
color: MyColours.app_main,
borderRadius: BorderRadius.all(
Radius.circular(ScreenUtil().setWidth(28)))),
child: Center(
child: Text(
widget.btnTitle,
style: TextStyle(
fontSize: ScreenUtil().setSp(28),
color: MyColours.color_ffffff),
),
),
),
)
: Container()
],
));
}
}
... ...
... ... @@ -69,6 +69,13 @@ class ExceptionPageState extends State<ExceptionPage> {
color: Colors.white,
);
break;
case PageState.NoPermission:
page = ErrorPage(
content: "未获取到通讯录权限",
callback: widget.callback,
btnTitle: '开启权限',
);
break;
default:
page = ErrorPage(
content: "哎呀~网络好像走失了呢",
... ...