import 'dart:async';
|
import 'dart:io';
|
import 'dart:typed_data';
|
import 'dart:ui';
|
|
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/material.dart';
|
import 'package:flutter/rendering.dart';
|
import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart';
|
import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart';
|
import 'package:flutter_baidu_mapapi_search/flutter_baidu_mapapi_search.dart';
|
import 'package:locations/ui/map/location_search.dart';
|
import 'package:locations/ui/mine/advice.dart';
|
import 'package:locations/ui/mine/permission.dart';
|
import 'package:locations/ui/mine/settings.dart';
|
import 'package:locations/ui/mine/share_to_friends.dart';
|
import 'package:locations/ui/mine/try_functions.dart';
|
import 'package:locations/ui/widget/button.dart';
|
import 'package:locations/utils/location_util.dart';
|
import 'package:locations/utils/map_util.dart';
|
import 'package:locations/utils/pageutils.dart';
|
import 'package:locations/utils/ui_constant.dart';
|
import 'package:path_provider/path_provider.dart';
|
import 'package:permission_handler/permission_handler.dart';
|
|
typedef OnPositionHiidenChange = void Function(bool hidden);
|
|
BMFMapController? _mapController;
|
|
class MyApp extends StatelessWidget {
|
// This widget is the root of your application.
|
@override
|
Widget build(BuildContext context) {
|
return MaterialApp(
|
title: 'Flutter Demo',
|
theme: ThemeData(
|
// This is the theme of your application.
|
//
|
// Try running your application with "flutter run". You'll see the
|
// application has a blue toolbar. Then, without quitting the app, try
|
// changing the primarySwatch below to Colors.green and then invoke
|
// "hot reload" (press "r" in the console where you ran "flutter run",
|
// or simply save your changes to "hot reload" in a Flutter IDE).
|
// Notice that the counter didn't reset back to zero; the application
|
// is not restarted.
|
primaryColor: Color.fromARGB(255, 150, 150, 150)),
|
home: LocationPage(title: ''),
|
);
|
}
|
}
|
|
class LocationPage extends StatefulWidget {
|
LocationPage({Key? key, required this.title}) : super(key: key);
|
|
// This widget is the home page of your application. It is stateful, meaning
|
// that it has a State object (defined below) that contains fields that affect
|
// how it looks.
|
|
// This class is the configuration for the state. It holds the values (in this
|
// case the title) provided by the parent (in this case the App widget) and
|
// used by the build method of the State. Fields in a Widget subclass are
|
// always marked "final".
|
|
final String title;
|
|
@override
|
_LocationPageState createState() => _LocationPageState();
|
}
|
|
class _LocationPageState extends State<LocationPage>
|
with AutomaticKeepAliveClientMixin {
|
GlobalKey rootWidgetKey = GlobalKey();
|
|
BMFMapOptions mapOptions = BMFMapOptions(
|
showMapScaleBar: false,
|
mapType: BMFMapType.Standard,
|
center: BMFCoordinate(39.917215, 116.380341),
|
mapScaleBarPosition: BMFPoint(0, 200),
|
zoomLevel: 12,
|
mapPadding: BMFEdgeInsets(left: 30, top: 0, right: 30, bottom: 200));
|
|
@override
|
void initState() {
|
super.initState();
|
}
|
|
@override
|
Widget build(BuildContext context) {
|
return Scaffold(
|
resizeToAvoidBottomInset: false,
|
backgroundColor: Colors.white,
|
body: Stack(
|
children: [
|
getMapView(),
|
PositionInfoPage(),
|
Positioned(
|
top: -100,
|
child:
|
RepaintBoundary(
|
key: rootWidgetKey,
|
child: Image.asset(
|
"assets/images/mine/icon_mine_default_portrait.png",
|
height: 33,
|
width: 33,
|
))),
|
Align(
|
alignment: Alignment.bottomCenter,
|
child: getAddLocationObjectView()),
|
],
|
));
|
}
|
|
//控件阴影
|
List<BoxShadow> getViewShadow() {
|
return [
|
BoxShadow(
|
blurRadius: 6.5,
|
spreadRadius: 1,
|
color: Color(0x4D0E96FF),
|
)
|
];
|
}
|
|
//获取地图视图
|
Widget getMapView() {
|
return Container(
|
child: BMFMapWidget(
|
onBMFMapCreated: (controller) {
|
_mapController = controller;
|
|
|
Timer(Duration(seconds: 3),(){
|
_capturePng().then((value) {
|
BMFMarker marker = BMFMarker(
|
position: BMFCoordinate(39.928617, 116.40329),
|
title: 'flutterMaker',
|
identifier: 'flutter_marker',
|
icon:value!.path);
|
|
/// 添加Marker
|
_mapController?.addMarker(marker);
|
});
|
});
|
|
|
|
},
|
mapOptions: mapOptions,
|
),
|
);
|
}
|
|
Future<File?> _capturePng() async {
|
await Permission.storage.request();
|
try {
|
RenderRepaintBoundary? boundary = rootWidgetKey.currentContext!
|
.findRenderObject() as RenderRepaintBoundary;
|
var image = await boundary.toImage(pixelRatio: 3.0);
|
ByteData? byteData = await image.toByteData(format: ImageByteFormat.png);
|
Uint8List pngBytes = byteData!.buffer.asUint8List();
|
Directory? tempDir = await getExternalStorageDirectory();
|
String tempPath = tempDir!.path;
|
String shareImgPath = "$tempPath/test.jpg";
|
File(shareImgPath!).writeAsBytesSync(pngBytes!);
|
int length=await File(shareImgPath!).length();
|
print("截图大小为:${length}");
|
return File(shareImgPath!);
|
} catch (e) {
|
print(e);
|
}
|
return null;
|
}
|
|
//添加想定位的人
|
Widget getAddLocationObjectView() {
|
return Container(
|
alignment: Alignment.topCenter,
|
height: 72,
|
margin: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
padding: const EdgeInsets.fromLTRB(0, 18, 0, 0),
|
decoration: BoxDecoration(
|
color: Colors.white,
|
borderRadius: BorderRadius.only(
|
topLeft: Radius.circular(10), topRight: Radius.circular(10)),
|
boxShadow: getViewShadow()),
|
child: Flex(
|
direction: Axis.horizontal,
|
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
children: [
|
Image.asset(
|
"assets/images/common/icon_person.png",
|
height: 17,
|
),
|
Container(
|
width: 11,
|
height: 1,
|
),
|
const Text(
|
"添加想定位的对象",
|
style: TextStyle(color: ColorConstant.theme, fontSize: 15),
|
)
|
],
|
),
|
);
|
}
|
|
@override
|
bool get wantKeepAlive => true;
|
}
|
|
//控件阴影
|
List<BoxShadow> getViewShadow() {
|
return [
|
BoxShadow(
|
blurRadius: 6.5,
|
spreadRadius: 1,
|
color: Color(0x4D0E96FF),
|
)
|
];
|
}
|
|
/*****************定位信息****************/
|
|
class PositionInfoPage extends StatefulWidget {
|
PositionInfoPage({Key? key}) : super(key: key);
|
|
@override
|
_PositionInfoPageState createState() => _PositionInfoPageState();
|
}
|
|
class _PositionInfoPageState extends State<PositionInfoPage>
|
with SingleTickerProviderStateMixin {
|
//位置信息是否隐藏
|
bool locationInfoHidden = true;
|
|
GlobalKey rootWidgetKey = GlobalKey();
|
|
@override
|
Widget build(BuildContext context) {
|
return Container(
|
padding: const EdgeInsets.fromLTRB(10, 35, 10, 0),
|
child: Flex(direction: Axis.vertical, children: [
|
//----------搜索框--------
|
Flex(
|
direction: Axis.horizontal,
|
children: [
|
Expanded(
|
child: InkWell(
|
onTap: () {
|
NavigatorUtil.navigateToNextPage(context, LocationSearchPage(),
|
(data) { });
|
},
|
child: Container(
|
alignment: Alignment.center,
|
padding: EdgeInsets.fromLTRB(13, 0, 13, 0),
|
height: 45,
|
decoration: BoxDecoration(
|
color: Colors.white,
|
borderRadius: BorderRadius.circular(10),
|
boxShadow: getViewShadow()),
|
child: Flex(
|
direction: Axis.horizontal,
|
children: [
|
Image.asset(
|
"assets/images/main/icon_location_search.png",
|
height: 19,
|
),
|
Container(
|
width: 10,
|
),
|
const Expanded(
|
child: Text("地图上找位置",
|
style: TextStyle(
|
fontSize: 14,
|
color: Color(0xFFC4CDD1))))
|
],
|
),
|
))),
|
InkWell(
|
onTap: () {
|
print("sos");
|
},
|
child: Container(
|
width: 45,
|
height: 45,
|
margin: const EdgeInsets.only(left: 8.5),
|
decoration: BoxDecoration(
|
color: Colors.white,
|
boxShadow: getViewShadow(),
|
borderRadius: BorderRadius.circular(23)),
|
alignment: Alignment.center,
|
child: Image.asset(
|
"assets/images/main/icon_location_sos.png",
|
height: 35,
|
),
|
))
|
],
|
),
|
//---------个人信息与定位信息---
|
Container(
|
height: 400,
|
child: Stack(
|
children: [
|
//位置信息
|
getPositionInfoView(context),
|
//个人信息
|
Container(
|
height: 100,
|
margin: EdgeInsets.only(top: 10),
|
padding: EdgeInsets.only(left: 15, top: 8, right: 15),
|
decoration: BoxDecoration(
|
borderRadius: BorderRadius.only(
|
bottomLeft:
|
Radius.circular(locationInfoHidden ? 10 : 0),
|
bottomRight:
|
Radius.circular(locationInfoHidden ? 10 : 0),
|
topLeft: Radius.circular(10),
|
topRight: Radius.circular(10)),
|
color: Colors.white,
|
boxShadow: getViewShadow()),
|
child: Stack(
|
alignment: Alignment.topCenter,
|
children: [
|
Flex(
|
mainAxisAlignment: MainAxisAlignment.center,
|
direction: Axis.horizontal,
|
children: [
|
Image.asset(
|
"assets/images/main/icon_location_change_person.png",
|
width: 13,
|
),
|
Text(
|
" 切换实时定位人",
|
style: TextStyle(
|
color: ColorConstant.theme, fontSize: 15),
|
)
|
],
|
),
|
//个人信息
|
Flex(
|
direction: Axis.horizontal,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
children: [
|
Image.asset(
|
"assets/images/mine/icon_mine_default_portrait.png",
|
height: 33,
|
width: 33,
|
),
|
Container(
|
width: 5,
|
),
|
Expanded(
|
child: Flex(
|
direction: Axis.vertical,
|
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
children: [
|
Text(
|
"我自己",
|
softWrap: false,
|
overflow: TextOverflow.ellipsis,
|
style: TextStyle(
|
color: Color(0xFFA0A0A0), fontSize: 18),
|
),
|
Container(
|
height: 2,
|
),
|
Text(
|
"ID:128312",
|
style: TextStyle(
|
color: Color(0xFFA0A0A0), fontSize: 12),
|
)
|
],
|
)),
|
Container(
|
width: 5,
|
),
|
Flex(
|
direction: Axis.vertical,
|
mainAxisAlignment: MainAxisAlignment.center,
|
children: [
|
MyOutlineButton(
|
"生成轨迹",
|
13,
|
height: 26,
|
width: 82,
|
fontSize: 12,
|
onClick: () {
|
print("生成轨迹");
|
},
|
),
|
Container(
|
height: 6,
|
),
|
MyOutlineButton(
|
"实时共享",
|
13,
|
height: 26,
|
width: 82,
|
fontSize: 12,
|
onClick: () {
|
print("实时共享");
|
},
|
),
|
])
|
],
|
)
|
],
|
),
|
),
|
|
//更多
|
Positioned(
|
left: MediaQuery.of(context).size.width / 2 - 10 - 70 / 2,
|
top: 80,
|
child: InkWell(
|
onTap: () {
|
setState(() {
|
locationInfoHidden = !locationInfoHidden;
|
});
|
},
|
child: Container(
|
width: 70,
|
height: 40,
|
child: Stack(
|
alignment: Alignment.bottomCenter,
|
children: [
|
Container(
|
height: 30,
|
width: 60,
|
margin: EdgeInsets.only(top: 0),
|
alignment: Alignment.center,
|
decoration: BoxDecoration(
|
color: Colors.white,
|
borderRadius:
|
BorderRadius.circular(15),
|
boxShadow: getViewShadow()),
|
),
|
Positioned(
|
top: 0,
|
child: Container(
|
height: 25,
|
width: 70,
|
alignment: Alignment.bottomCenter,
|
|
decoration: BoxDecoration(
|
color: Colors.white,
|
),
|
// child: Text(
|
// "收起",
|
// style: TextStyle(
|
// color: ColorConstant.theme,
|
// fontSize: 11),
|
// )
|
)),
|
Positioned(
|
bottom: 5,
|
child: Text(
|
locationInfoHidden ? "展开" : "收起",
|
style: TextStyle(
|
color: ColorConstant.theme,
|
fontSize: 11),
|
)),
|
]))))
|
],
|
)),
|
]));
|
}
|
|
Widget getPositionInfoView(BuildContext context) {
|
if (!locationInfoHidden) {
|
return Positioned(
|
top: 110,
|
child: ClipRRect(
|
borderRadius: const BorderRadius.only(
|
bottomLeft: Radius.circular(10),
|
bottomRight: Radius.circular(10)),
|
child: BackdropFilter(
|
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
|
child: Container(
|
padding: const EdgeInsets.all(18),
|
height: 120,
|
width: MediaQuery.of(context).size.width - 10 * 2,
|
color: Colors.white.withAlpha(180),
|
child: Flex(
|
mainAxisAlignment: MainAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
direction: Axis.vertical,
|
children: [
|
Container(
|
padding: const EdgeInsets.fromLTRB(12, 5, 12, 5),
|
decoration: BoxDecoration(
|
color: const Color(0xFFCACDD3),
|
borderRadius: BorderRadius.circular(20)),
|
child: const Text(
|
"2021.08.08 12:00",
|
style: TextStyle(color: Colors.white, fontSize: 10),
|
),
|
),
|
Container(
|
height: 2,
|
),
|
Flex(
|
direction: Axis.horizontal,
|
children: [
|
Image.asset(
|
"assets/images/main/icon_location_position_name.png",
|
height: 16,
|
),
|
Text(
|
" 当前位置:",
|
style: TextStyle(
|
color: Color(0xFF999999), fontSize: 12),
|
),
|
Expanded(
|
child: Text(
|
"重庆市重庆市重庆市重庆市重庆市重庆市重庆市重庆庆市重庆市重庆",
|
softWrap: false,
|
overflow: TextOverflow.ellipsis,
|
style: TextStyle(
|
color: Color(0xFFBABABA), fontSize: 12),
|
))
|
],
|
),
|
Container(
|
height: 4,
|
),
|
Container(
|
child: Flex(
|
direction: Axis.horizontal,
|
children: [
|
Image.asset(
|
"assets/images/main/icon_location_position_location.png",
|
height: 15,
|
),
|
Text(
|
" 经 纬 度:",
|
style: TextStyle(
|
color: Color(0xFF999999), fontSize: 12),
|
),
|
Expanded(
|
child: Text(
|
"N 41141.1233,W 28741.389",
|
softWrap: false,
|
overflow: TextOverflow.ellipsis,
|
style: TextStyle(
|
color: Color(0xFFBABABA), fontSize: 12),
|
))
|
],
|
)),
|
Container(
|
height: 5,
|
),
|
Flex(
|
direction: Axis.horizontal,
|
mainAxisAlignment: MainAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
children: [
|
Text(
|
"查看全部共100次定位 ",
|
style: TextStyle(
|
color: Color(0xFF9DAAB3), fontSize: 10),
|
),
|
Image.asset(
|
"assets/images/main/icon_location_position_more.png",
|
height: 10,
|
),
|
],
|
),
|
],
|
),
|
))));
|
} else {
|
return Container();
|
}
|
}
|
}
|