amap_search_fluttify

This commit is contained in:
2024-11-17 15:59:37 +08:00
commit 731cf46ce1
435 changed files with 218481 additions and 0 deletions

View File

@ -0,0 +1,145 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:amap_search_fluttify_example/widgets/function_item.widget.dart';
import 'package:core_location_fluttify/core_location_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
class GetAddressDescScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('获取地址描述数据')),
body: ListView(
children: <Widget>[
const FunctionItem(
label: '地理编码(地址转坐标)',
sublabel: 'AddressEncodeScreen',
target: AddressEncodeScreen(),
),
FunctionItem(
label: '逆地理编码(坐标转地址)',
sublabel: 'AddressDecodeScreen',
target: AddressDecodeScreen(),
),
],
),
);
}
}
/// 地理编码(地址转坐标)
class AddressEncodeScreen extends StatefulWidget {
const AddressEncodeScreen({Key? key}) : super(key: key);
@override
_AddressEncodeScreenState createState() => _AddressEncodeScreenState();
}
class _AddressEncodeScreenState extends State<AddressEncodeScreen> {
final _keywordController = TextEditingController(text: '阿里巴巴');
final _cityController = TextEditingController(text: '杭州');
List<Geocode> _geocodeList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('地理编码(地址转坐标)')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _cityController,
decoration: const InputDecoration(hintText: '输入城市'),
),
RaisedButton(
onPressed: () async {
final geocodeList = await AmapSearch.instance.searchGeocode(
_keywordController.text,
city: _cityController.text,
);
setState(() {
_geocodeList = geocodeList;
});
},
child: const Text('搜索'),
),
if (_geocodeList.isNotEmpty) Text(_geocodeList.toString()),
],
),
);
}
}
/// 逆地理编码(坐标转地址)
class AddressDecodeScreen extends StatefulWidget {
@override
_AddressDecodeScreenState createState() => _AddressDecodeScreenState();
}
class _AddressDecodeScreenState extends State<AddressDecodeScreen> {
final _latController = TextEditingController(text: '39.9824');
final _lngController = TextEditingController(text: '116.3053');
final _radiusController = TextEditingController(text: '200.0');
ReGeocode? _reGeocode;
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('逆地理编码(坐标转地址)')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
DecoratedRow(
children: <Widget>[
Flexible(
child: TextFormField(
controller: _latController,
decoration: const InputDecoration(hintText: '输入纬度'),
),
),
Flexible(
child: TextFormField(
controller: _lngController,
decoration: const InputDecoration(hintText: '输入经度'),
),
),
],
),
TextFormField(
controller: _radiusController,
decoration: const InputDecoration(hintText: '输入范围半径'),
),
RaisedButton(
onPressed: () async {
final reGeocodeList = await AmapSearch.instance.searchReGeocode(
LatLng(
double.parse(_latController.text),
double.parse(_lngController.text),
),
radius: 200.0,
);
setState(() {
_reGeocode = reGeocodeList;
});
},
child: const Text('搜索'),
),
Expanded(
child: SingleChildScrollView(
child: Text(_reGeocode?.toString() ?? ''),
),
),
],
),
);
}
}

View File

@ -0,0 +1,50 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:amap_search_fluttify_example/widgets/scrollable_text.widget.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 获取公交数据
class GetBusInfoScreen extends StatefulWidget {
@override
_GetBusInfoScreenState createState() => _GetBusInfoScreenState();
}
class _GetBusInfoScreenState extends State<GetBusInfoScreen> {
final _keywordController = TextEditingController(text: '武林广场');
final _cityController = TextEditingController(text: '杭州');
String _busStation = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('获取公交数据')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入公交站点名称'),
),
TextFormField(
controller: _cityController,
decoration: const InputDecoration(hintText: '输入城市'),
),
RaisedButton(
onPressed: () async {
final busStation = await AmapSearch.instance.searchBusStation(
stationName: _keywordController.text,
city: _cityController.text,
);
_busStation = await busStation.toFutureString();
setState(() {});
},
child: const Text('搜索'),
),
Expanded(child: ScrollableText(_busStation)),
],
),
);
}
}

View File

@ -0,0 +1,45 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 获取行政区划数据
class GetDistrictInfoScreen extends StatefulWidget {
@override
_GetDistrictInfoScreenState createState() => _GetDistrictInfoScreenState();
}
class _GetDistrictInfoScreenState extends State<GetDistrictInfoScreen> {
final _keywordController = TextEditingController(text: '西湖区');
String _district = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('获取行政区划数据')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入地区'),
),
RaisedButton(
onPressed: () async {
final district = await AmapSearch.instance.searchDistrict(
_keywordController.text,
showBoundary: true,
showChild: true,
);
_district = district.toString();
setState(() {});
},
child: const Text('搜索'),
),
Expanded(child: SingleChildScrollView(child: Text(_district))),
],
),
);
}
}

View File

@ -0,0 +1,234 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:amap_search_fluttify_example/widgets/function_item.widget.dart';
import 'package:amap_search_fluttify_example/widgets/scrollable_text.widget.dart';
import 'package:core_location_fluttify/core_location_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
class GetPoiScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('获取POI数据')),
body: ListView(
children: <Widget>[
FunctionItem(
label: '关键字检索POI',
sublabel: 'KeywordPoiScreen',
target: KeywordPoiScreen(),
),
FunctionItem(
label: '周边检索POI',
sublabel: 'AroundPoiScreen',
target: AroundPoiScreen(),
),
FunctionItem(
label: '输入提示',
sublabel: 'InputTipScreen',
target: InputTipScreen(),
),
],
),
);
}
}
/// 关键字检索POI
class KeywordPoiScreen extends StatefulWidget {
@override
_KeywordPoiScreenState createState() => _KeywordPoiScreenState();
}
class _KeywordPoiScreenState extends State<KeywordPoiScreen> {
final _keywordController = TextEditingController(text: '肯德基');
final _cityController = TextEditingController(text: '杭州');
int _page = 1;
List<String> _poiTitleList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('关键字检索POI')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _cityController,
decoration: const InputDecoration(hintText: '输入城市'),
),
ElevatedButton(
onPressed: () async {
final poiList = await AmapSearch.instance.searchKeyword(
_keywordController.text,
city: _cityController.text,
);
setState(() {
_poiTitleList = poiList.map((it) => it.toString()).toList();
});
},
child: const Text('搜索'),
),
ElevatedButton(
onPressed: () async {
final poiList = await AmapSearch.instance.searchKeyword(
_keywordController.text,
city: _cityController.text,
page: ++_page,
);
setState(() {
_poiTitleList = poiList.map((it) => it.toString()).toList();
});
},
child: const Text('下一页'),
),
Expanded(child: ScrollableText(_poiTitleList.join("\n"))),
],
),
);
}
}
/// 附近检索POI
class AroundPoiScreen extends StatefulWidget {
@override
_AroundPoiScreenState createState() => _AroundPoiScreenState();
}
class _AroundPoiScreenState extends State<AroundPoiScreen> {
final _keywordController = TextEditingController();
final _typeController = TextEditingController();
final _latController = TextEditingController(text: '29.08');
final _lngController = TextEditingController(text: '119.65');
int _page = 1;
List<String> _poiTitleList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('周边检索POI')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _typeController,
decoration: const InputDecoration(hintText: '输入类别'),
),
DecoratedRow(
children: <Widget>[
Flexible(
child: TextField(
controller: _latController,
decoration: const InputDecoration(hintText: '输入纬度'),
),
),
SPACE_4_HORIZONTAL,
Flexible(
child: TextField(
controller: _lngController,
decoration: const InputDecoration(hintText: '输入经度'),
),
),
],
),
RaisedButton(
onPressed: () async {
final poiList = await AmapSearch.instance.searchAround(
LatLng(
double.tryParse(_latController.text) ?? 29.08,
double.tryParse(_lngController.text) ?? 119.65,
),
keyword: _keywordController.text,
type: _typeController.text,
);
setState(() {
_poiTitleList = poiList.map((it) => it.toString()).toList();
});
},
child: const Text('搜索'),
),
RaisedButton(
onPressed: () async {
final poiList = await AmapSearch.instance.searchAround(
LatLng(
double.tryParse(_latController.text) ?? 29.08,
double.tryParse(_lngController.text) ?? 119.65,
),
keyword: _keywordController.text,
type: _typeController.text,
page: ++_page,
);
setState(() {
_poiTitleList = poiList.map((it) => it.toString()).toList();
});
},
child: const Text('下一页'),
),
Expanded(child: ScrollableText(_poiTitleList.join("\n"))),
],
),
);
}
}
/// 输入提示
class InputTipScreen extends StatefulWidget {
@override
_InputTipScreenState createState() => _InputTipScreenState();
}
class _InputTipScreenState extends State<InputTipScreen> {
final _keywordController = TextEditingController(text: '肯德基');
final _cityController = TextEditingController(text: '杭州');
List<InputTip> _inputTipList = [];
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('输入内容自动提示')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入关键字'),
),
TextFormField(
controller: _cityController,
decoration: const InputDecoration(hintText: '输入所在城市'),
),
RaisedButton(
onPressed: () async {
final inputTipList = await AmapSearch.instance.fetchInputTips(
_keywordController.text,
city: _cityController.text,
);
setState(() => _inputTipList = inputTipList);
},
child: const Text('搜索'),
),
Expanded(child: ScrollableText(_inputTipList.join("\n"))),
],
),
);
}
}

View File

@ -0,0 +1,42 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 获取天气数据
class GetWeatherInfoScreen extends StatefulWidget {
@override
_GetWeatherInfoScreenState createState() => _GetWeatherInfoScreenState();
}
class _GetWeatherInfoScreenState extends State<GetWeatherInfoScreen> {
final _keywordController = TextEditingController(text: '杭州');
String _district = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('获取天气数据')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
TextFormField(
controller: _keywordController,
decoration: const InputDecoration(hintText: '输入地区'),
),
RaisedButton(
onPressed: () async {
final district = await AmapSearch.instance
.searchDistrict(_keywordController.text);
_district = district.toString();
setState(() {});
},
child: const Text('搜索'),
),
Expanded(child: SingleChildScrollView(child: Text(_district))),
],
),
);
}
}

129
example/lib/main.dart Normal file
View File

@ -0,0 +1,129 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:flutter/material.dart';
import 'get_map_data/get_address_desc.screen.dart';
import 'get_map_data/get_bus_info.screen.dart';
import 'get_map_data/get_district_info.screen.dart';
import 'get_map_data/get_poi.screen.dart';
import 'get_map_data/get_weather_info.screen.dart';
import 'route_plan/route_bus.screen.dart';
import 'route_plan/route_drive.screen.dart';
import 'route_plan/route_ride.screen.dart';
import 'route_plan/route_walk.screen.dart';
import 'widgets/function_group.widget.dart';
import 'widgets/function_item.widget.dart';
import 'widgets/todo.screen.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await AmapSearch.instance.init('f583e0d5b70400167993615c3adc3ced');
await AmapSearch.instance.updatePrivacyShow(true);
await AmapSearch.instance.updatePrivacyAgree(true);
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return const MaterialApp(home: Home());
}
}
class Home extends StatelessWidget {
const Home({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('AMaps examples')),
body: ListView(
children: <Widget>[
FunctionGroup(
headLabel: '获取地图数据',
children: <Widget>[
FunctionItem(
label: '获取POI数据',
sublabel: 'GetPoiScreen',
target: GetPoiScreen(),
),
FunctionItem(
label: '获取地址描述数据',
sublabel: 'GetAddressDescScreen',
target: GetAddressDescScreen(),
),
FunctionItem(
label: '获取行政区划数据',
sublabel: 'GetDistrictInfoScreen',
target: GetDistrictInfoScreen(),
),
FunctionItem(
label: '获取公交数据',
sublabel: 'GetBusInfoScreenScreen',
target: GetBusInfoScreen(),
),
FunctionItem(
label: '后获取天气数据',
sublabel: 'GetWeatherInfoScreen',
target: GetWeatherInfoScreen(),
),
FunctionItem(
label: '获取业务数据(云图功能)',
sublabel: 'TODO',
target: TodoScreen(),
),
FunctionItem(
label: '获取交通态势信息',
sublabel: 'TODO',
target: TodoScreen(),
),
],
),
FunctionGroup(
headLabel: '出行路线规划',
children: <Widget>[
FunctionItem(
label: '驾车出行路线规划',
sublabel: 'RouteDriveScreen',
target: RouteDriveScreen(),
),
FunctionItem(
label: '步行出行路线规划',
sublabel: 'RouteWalkScreen',
target: RouteWalkScreen(),
),
FunctionItem(
label: '公交出行路线规划',
sublabel: 'RouteBusScreen',
target: RouteBusScreen(),
),
FunctionItem(
label: '骑行出行路线规划',
sublabel: 'RouteRideScreen',
target: RouteRideScreen(),
),
FunctionItem(
label: '货车出行路线规划',
sublabel: 'TODO',
target: TodoScreen(),
),
FunctionItem(
label: '未来出行路线规划',
sublabel: 'TODO',
target: TodoScreen(),
),
],
),
],
),
);
}
}

View File

@ -0,0 +1,97 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:core_location_fluttify/core_location_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 公交路线规划
class RouteBusScreen extends StatefulWidget {
@override
_RouteBusScreenState createState() => _RouteBusScreenState();
}
class _RouteBusScreenState extends State<RouteBusScreen> {
final _fromLatController = TextEditingController(text: '30.219933');
final _fromLngController = TextEditingController(text: '120.023728');
final _toLatController = TextEditingController(text: '30.27065');
final _toLngController = TextEditingController(text: '120.163117');
String _routeResult = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('公交路线规划')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('起点:'),
Flexible(
child: TextFormField(
controller: _fromLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _fromLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点经度'),
),
),
],
),
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('终点:'),
Flexible(
child: TextFormField(
controller: _toLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _toLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点经度'),
),
),
],
),
RaisedButton(
onPressed: () async {
final routeResult = await AmapSearch.instance.searchBusRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
city: '杭州',
);
routeResult
.toFutureString()
.then((it) => setState(() => _routeResult = it));
},
child: const Text('搜索'),
),
Expanded(
child: SingleChildScrollView(
child: Text(_routeResult),
),
),
],
),
);
}
}

View File

@ -0,0 +1,100 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:core_location_fluttify/core_location_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 驾车路线规划
class RouteDriveScreen extends StatefulWidget {
@override
_RouteDriveScreenState createState() => _RouteDriveScreenState();
}
class _RouteDriveScreenState extends State<RouteDriveScreen> {
final _fromLatController = TextEditingController(text: '30.219933');
final _fromLngController = TextEditingController(text: '120.023728');
final _toLatController = TextEditingController(text: '30.27065');
final _toLngController = TextEditingController(text: '120.163117');
String _routeResult = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('驾车路线规划')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('起点:'),
Flexible(
child: TextFormField(
controller: _fromLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _fromLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点经度'),
),
),
],
),
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('终点:'),
Flexible(
child: TextFormField(
controller: _toLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _toLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点经度'),
),
),
],
),
RaisedButton(
onPressed: () async {
try {
final routeResult = await AmapSearch.instance.searchDriveRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
);
routeResult
.toFutureString()
.then((it) => setState(() => _routeResult = it));
} catch (e) {
setState(() => _routeResult = e.toString());
}
},
child: const Text('搜索'),
),
Expanded(
child: SingleChildScrollView(
child: Text(_routeResult),
),
),
],
),
);
}
}

View File

@ -0,0 +1,92 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:core_location_fluttify/core_location_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 骑行路线规划
class RouteRideScreen extends StatefulWidget {
@override
_RouteRideScreenState createState() => _RouteRideScreenState();
}
class _RouteRideScreenState extends State<RouteRideScreen> {
final _fromLatController = TextEditingController(text: '30.219933');
final _fromLngController = TextEditingController(text: '120.023728');
final _toLatController = TextEditingController(text: '30.27065');
final _toLngController = TextEditingController(text: '120.163117');
String _routeResult = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('骑行路线规划')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('起点:'),
Flexible(
child: TextFormField(
controller: _fromLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _fromLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点经度'),
),
),
],
),
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('终点:'),
Flexible(
child: TextFormField(
controller: _toLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _toLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点经度'),
),
),
],
),
RaisedButton(
onPressed: () async {
final routeResult = await AmapSearch.instance.searchRideRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
);
routeResult
.toFutureString()
.then((it) => setState(() => _routeResult = it));
},
child: const Text('搜索'),
),
Expanded(child: SingleChildScrollView(child: Text(_routeResult))),
],
),
);
}
}

View File

@ -0,0 +1,96 @@
import 'package:amap_search_fluttify/amap_search_fluttify.dart';
import 'package:core_location_fluttify/core_location_fluttify.dart';
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
/// 步行路线规划
class RouteWalkScreen extends StatefulWidget {
@override
_RouteWalkScreenState createState() => _RouteWalkScreenState();
}
class _RouteWalkScreenState extends State<RouteWalkScreen> {
final _fromLatController = TextEditingController(text: '30.219933');
final _fromLngController = TextEditingController(text: '120.023728');
final _toLatController = TextEditingController(text: '30.27065');
final _toLngController = TextEditingController(text: '120.163117');
String _routeResult = '';
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('步行路线规划')),
body: DecoratedColumn(
padding: const EdgeInsets.all(kSpace16),
children: <Widget>[
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('起点:'),
Flexible(
child: TextFormField(
controller: _fromLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _fromLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入出发点经度'),
),
),
],
),
DecoratedRow(
itemSpacing: kSpace8,
children: <Widget>[
const Text('终点:'),
Flexible(
child: TextFormField(
controller: _toLatController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点纬度'),
),
),
Flexible(
child: TextFormField(
controller: _toLngController,
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: '输入终点经度'),
),
),
],
),
RaisedButton(
onPressed: () async {
final routeResult = await AmapSearch.instance.searchWalkRoute(
from: LatLng(
double.parse(_fromLatController.text),
double.parse(_fromLngController.text),
),
to: LatLng(
double.parse(_toLatController.text),
double.parse(_toLngController.text),
),
);
routeResult
.toFutureString()
.then((it) => setState(() => _routeResult = it));
},
child: const Text('搜索'),
),
Expanded(
child: SingleChildScrollView(
child: Text(_routeResult),
),
),
],
),
);
}
}

View File

@ -0,0 +1,13 @@
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:permission_handler/permission_handler.dart';
Future<bool> requestPermission() async {
final status = await Permission.location.request();
if (status == PermissionStatus.granted) {
return true;
} else {
toast('需要定位权限!');
return false;
}
}

View File

@ -0,0 +1 @@
export 'misc.dart';

View File

@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
class Button extends StatelessWidget {
const Button({
Key? key,
required this.label,
required this.onPressed,
}) : super(key: key);
final String label;
final ValueChanged<BuildContext> onPressed;
@override
Widget build(BuildContext context) {
return RaisedButton(
padding: const EdgeInsets.symmetric(vertical: 16),
color: Colors.black,
onPressed: () => onPressed(context),
shape: const StadiumBorder(),
child: Text(
label,
style: const TextStyle(color: Colors.white, fontSize: 15),
),
);
}
}

View File

@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
//region space
const kSpaceZero = 0.0;
const kSpaceTiny = 1.0;
const kSpaceSmall = 4.0;
const kSpace8 = 8.0;
const kSpaceLittleBig = 12.0;
const kSpace16 = 16.0;
const kSpaceLarge = 24.0;
const kSpaceHuge = 32.0;
const kSpaceGiant = 64.0;
const SPACE_ZERO = SizedBox.shrink();
const SPACE_TINY = SizedBox(width: kSpaceTiny, height: kSpaceTiny);
const SPACE_TINY_HORIZONTAL = SizedBox(width: kSpaceTiny, height: kSpaceZero);
const SPACE_TINY_VERTICAL = SizedBox(width: kSpaceZero, height: kSpaceTiny);
const SPACE_SMALL = SizedBox(width: kSpaceSmall, height: kSpaceSmall);
const SPACE_4_HORIZONTAL = SizedBox(width: kSpaceSmall, height: kSpaceZero);
const SPACE_SMALL_VERTICAL = SizedBox(width: kSpaceZero, height: kSpaceSmall);
const SPACE_NORMAL = SizedBox(width: kSpace8, height: kSpace8);
const SPACE_NORMAL_HORIZONTAL = SizedBox(width: kSpace8, height: kSpaceZero);
const SPACE_NORMAL_VERTICAL = SizedBox(width: kSpaceZero, height: kSpace8);
const SPACE_LITTLE_BIG =
SizedBox(width: kSpaceLittleBig, height: kSpaceLittleBig);
const SPACE_LITTLE_BIG_HORIZONTAL =
SizedBox(width: kSpaceLittleBig, height: kSpaceZero);
const SPACE_LITTLE_BIG_VERTICAL =
SizedBox(width: kSpaceZero, height: kSpaceLittleBig);
const SPACE_BIG = SizedBox(width: kSpace16, height: kSpace16);
const SPACE_BIG_HORIZONTAL = SizedBox(width: kSpace16, height: kSpaceZero);
const SPACE_BIG_VERTICAL = SizedBox(width: kSpaceZero, height: kSpace16);
const SPACE_LARGE = SizedBox(width: kSpaceLarge, height: kSpaceLarge);
const SPACE_LARGE_HORIZONTAL = SizedBox(width: kSpaceLarge, height: kSpaceZero);
const SPACE_LARGE_VERTICAL = SizedBox(width: kSpaceZero, height: kSpaceLarge);
const SPACE_HUGE = SizedBox(width: kSpaceHuge, height: kSpaceHuge);
const SPACE_HUGE_HORIZONTAL = SizedBox(width: kSpaceHuge, height: kSpaceZero);
const SPACE_HUGE_VERTICAL = SizedBox(width: kSpaceZero, height: kSpaceHuge);
const SPACE_GIANT = SizedBox(width: kSpaceGiant, height: kSpaceGiant);
const SPACE_GIANT_HORIZONTAL = SizedBox(width: kSpaceGiant, height: kSpaceZero);
const SPACE_GIANT_VERTICAL = SizedBox(width: kSpaceZero, height: kSpaceGiant);
const kDividerTiny = Divider(height: kSpaceTiny);
const kDividerSmall = Divider(height: kSpaceSmall);
const kDividerNormal = Divider();
const kDividerLittleBig = Divider(height: kSpaceLittleBig);
const kDividerBig = Divider(height: kSpace16);
const kDividerLarge = Divider(height: kSpaceLarge);
const kDividerHuge = Divider(height: kSpaceHuge);
const kDividerGiant = Divider(height: kSpaceGiant);
//endregion
//region text
const kTextNormal = 16.0;
const kTextBig = 18.0;
//endregion
//region elevation
const kElevationZero = 0.0;
const kElevationTiny = 1.0;
const kElevationSmall = 2.0;
const kElevationNormal = 4.0;
const kElevationBig = 8.0;
const kElevationHuge = 16.0;
const kElevationGiant = 32.0;
//endregion

View File

@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
class FunctionGroup extends StatelessWidget {
const FunctionGroup({
Key? key,
required this.headLabel,
this.children = const [],
}) : super(key: key);
final String headLabel;
final List<Widget> children;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Text(headLabel,
style: Theme.of(context).textTheme.headline6),
),
const Divider(height: 1, indent: 16),
],
), ...children,
],
),
);
}
}

View File

@ -0,0 +1,34 @@
import 'package:flutter/material.dart';
class FunctionItem extends StatelessWidget {
const FunctionItem({
Key? key,
required this.label,
required this.sublabel,
required this.target,
}) : super(key: key);
final String label;
final String sublabel;
final Widget target;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
ListTile(
title: Text(label),
subtitle: Text(sublabel),
trailing: const Icon(Icons.keyboard_arrow_right),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => target),
);
},
),
const Divider(height: 1, indent: 16),
],
);
}
}

View File

@ -0,0 +1,17 @@
import 'package:decorated_flutter/decorated_flutter.dart';
import 'package:flutter/material.dart';
class FutureText extends StatelessWidget {
const FutureText(this.data, {Key? key}) : super(key: key);
final Future<String> data;
@override
Widget build(BuildContext context) {
return SingleSubscriber<String>(
future: data,
showLoading: false,
builder: (data) => Text(data),
);
}
}

View File

@ -0,0 +1,12 @@
import 'package:flutter/material.dart';
class ScrollableText extends StatelessWidget {
final String data;
const ScrollableText(this.data, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(child: Text(data));
}
}

View File

@ -0,0 +1,209 @@
import 'package:flutter/material.dart';
const SPACE_NORMAL = SizedBox(width: 8, height: 8);
const kDividerTiny = Divider(height: 1);
/// 连续设置
class ContinuousSetting extends StatefulWidget {
const ContinuousSetting({
Key? key,
required this.head,
required this.onChanged,
this.min = 0,
this.max = 1,
}) : super(key: key);
final String head;
final ValueChanged<double> onChanged;
final double min;
final double max;
@override
_ContinuousSettingState createState() => _ContinuousSettingState();
}
class _ContinuousSettingState extends State<ContinuousSetting> {
late double _value;
@override
void initState() {
super.initState();
_value = 0;
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(
left: 16,
top: 16,
right: 16,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(widget.head, style: Theme.of(context).textTheme.subtitle1),
SPACE_NORMAL,
Slider(
value: _value,
min: widget.min,
max: widget.max,
onChanged: (_) {},
onChangeEnd: (value) {
setState(() {
_value = value;
widget.onChanged(value);
});
},
),
kDividerTiny,
],
),
);
}
}
/// 离散设置
class DiscreteSetting extends StatelessWidget {
const DiscreteSetting({
Key? key,
required this.head,
required this.options,
required this.onSelected,
}) : super(key: key);
final String head;
final List<String> options;
final ValueChanged<String> onSelected;
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
PopupMenuButton<String>(
onSelected: onSelected,
child: Padding(
padding: const EdgeInsets.all(16),
child: Text(head, style: Theme.of(context).textTheme.subtitle1),
),
itemBuilder: (context) {
return options
.map((value) => PopupMenuItem<String>(
value: value,
child: Text(value),
))
.toList();
},
),
kDividerTiny,
],
);
}
}
/// 颜色设置
class ColorSetting extends StatelessWidget {
const ColorSetting({
Key? key,
required this.head,
required this.onSelected,
}) : super(key: key);
final String head;
final ValueChanged<Color?> onSelected;
@override
Widget build(BuildContext context) {
return DiscreteSetting(
head: head,
options: const ['绿色', '红色', '黄色'],
onSelected: (value) {
Color? color;
switch (value) {
case '绿色':
color = Colors.green.withOpacity(0.6);
break;
case '红色':
color = Colors.red.withOpacity(0.6);
break;
case '黄色':
color = Colors.yellow.withOpacity(0.6);
break;
}
onSelected(color);
},
);
}
}
/// 二元设置
class BooleanSetting extends StatefulWidget {
const BooleanSetting({
Key? key,
required this.head,
required this.onSelected,
this.selected = false,
}) : super(key: key);
final String head;
final ValueChanged<bool> onSelected;
final bool selected;
@override
_BooleanSettingState createState() => _BooleanSettingState();
}
class _BooleanSettingState extends State<BooleanSetting> {
late bool _selected;
@override
void initState() {
super.initState();
_selected = widget.selected;
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
SwitchListTile(
title: Text(widget.head),
value: _selected,
onChanged: (selected) {
setState(() {
_selected = selected;
widget.onSelected(selected);
});
},
),
kDividerTiny,
],
);
}
}
/// 输入文字
class TextSetting extends StatelessWidget {
final String leadingString;
final String hintString;
const TextSetting({
Key? key,
required this.leadingString,
required this.hintString,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
leading: Text(leadingString),
title: TextFormField(
decoration: InputDecoration(
hintText: hintString,
),
),
);
}
}

View File

@ -0,0 +1,11 @@
import 'package:flutter/material.dart';
class TodoScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Todo')),
body: const Center(child: Text('Todo')),
);
}
}