Flutter商店定位插件store_locator的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter商店定位插件store_locator的使用

插件介绍

store_locator 是一个用于Flutter的插件,它允许在iOS和Android设备上动态显示地图标记。该插件基于Haversine公式或其他类似算法来获取位置信息,并根据这些信息显示地图标记。

安装

首先,在pubspec.yaml文件中添加store_locator作为依赖项:

dependencies:
  store_locator: ^x.x.x

同时,请确保已正确导入google_maps_flutter库,可以参考其官方文档进行安装和配置。

导入

在代码中导入store_locator包:

import 'package:store_locator/store_locator.dart';

示例代码

下面是一个完整的示例代码,展示了如何使用store_locator插件来显示地图标记。

import 'package:dio/dio.dart';
import 'package:example/store_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:store_locator/store_locator.dart';
import 'dart:ui' as ui;

void main() {
  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  // This widget is the root of your application.
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const StoreLocatorDemo(title: 'Store Locator Demo'),
    );
  }
}

class StoreLocatorDemo extends StatefulWidget {
  const StoreLocatorDemo({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<StoreLocatorDemo> createState() => _StoreLocatorDemoState();
}

class _StoreLocatorDemoState extends State<StoreLocatorDemo> {
  static const String url =
      "https://627bb38fa01146a853238cb9.mockapi.io/api/v11/";

  BitmapDescriptor? customMarker;

  static BaseOptions options =
      BaseOptions(baseUrl: url, responseType: ResponseType.json);

  [@override](/user/override)
  void initState() {
    super.initState();
    getMarkerIcon();
  }

  Future<void> getMarkerIcon() async {
    ByteData data = await rootBundle.load('assets/marker.png');
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),
        targetWidth: 100);
    ui.FrameInfo fi = await codec.getNextFrame();
    final Uint8List markerIcon =
        (await fi.image.toByteData(format: ui.ImageByteFormat.png))!
            .buffer
            .asUint8List();
    setState(() {
      customMarker = BitmapDescriptor.bytes(markerIcon);
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
        centerTitle: true,
      ),
      body: Center(
        child: StoreLocator<Store>(
          resetMarkers: false,
          mapConfiguration: const MapConfiguration(
            initialCameraPosition: CameraPosition(
              target: LatLng(43.2116397, 13.6077776),
              zoom: 10,
            ),
          ),
          positionCallback: (position) async {
            // You can pass latitude and longitude like that:
            // Response response = await Dio(options).get('stores', queryParameters: {
            //   "latitude": position.latitude,
            //   "longitude": position.longitude,
            // });

            Response response = await Dio(options).get('stores');
            if (response.statusCode == 200 || response.statusCode == 201) {
              return storesFromJson(response.data);
            }
            return [];
          },
          markerBuilder: (store) {
            return Marker(
              markerId: MarkerId(store.id.toString()),
              icon: customMarker ?? BitmapDescriptor.defaultMarker,
              position: LatLng(store.latitude, store.longitude),
              infoWindow: InfoWindow(
                title: store.name,
                snippet: store.city,
              ),
            );
          },
        ),
      ),
    );
  }
}

更多关于Flutter商店定位插件store_locator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter商店定位插件store_locator的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用store_locator插件的一个示例代码案例。store_locator插件通常用于实现商店定位功能,允许用户查找附近的商店。以下是一个基本的实现步骤和代码示例。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加store_locator依赖:

dependencies:
  flutter:
    sdk: flutter
  store_locator: ^最新版本号  # 请替换为实际最新版本号

然后运行flutter pub get来安装依赖。

2. 导入插件

在你的Dart文件中导入store_locator插件:

import 'package:store_locator/store_locator.dart';

3. 配置商店数据

你需要准备一个包含商店信息的列表。通常这些信息会来自你的后端API,但为了演示,这里我们使用硬编码的数据:

List<Store> stores = [
  Store(
    id: '1',
    name: 'Store One',
    address: '123 Main St, Anytown, USA',
    latitude: 37.7749,
    longitude: -122.4194,
    phoneNumber: '+1234567890',
    website: 'https://www.storeone.com',
    email: 'info@storeone.com',
    image: 'assets/images/store1.png',
  ),
  Store(
    id: '2',
    name: 'Store Two',
    address: '456 Elm St, Anytown, USA',
    latitude: 37.7750,
    longitude: -122.4195,
    phoneNumber: '+0987654321',
    website: 'https://www.storetwo.com',
    email: 'info@storetwo.com',
    image: 'assets/images/store2.png',
  ),
  // 添加更多商店...
];

4. 使用StoreLocator

在你的UI组件中,使用StoreLocator小部件来显示商店定位功能:

import 'package:flutter/material.dart';
import 'package:store_locator/store_locator.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Store Locator Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: StoreLocatorScreen(stores: stores),
    );
  }
}

class StoreLocatorScreen extends StatefulWidget {
  final List<Store> stores;

  StoreLocatorScreen({required this.stores});

  @override
  _StoreLocatorScreenState createState() => _StoreLocatorScreenState();
}

class _StoreLocatorScreenState extends State<StoreLocatorScreen> {
  late StoreLocatorController _controller;

  @override
  void initState() {
    super.initState();
    _controller = StoreLocatorController(stores: widget.stores);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Store Locator'),
      ),
      body: StoreLocator(
        controller: _controller,
        userLocation: UserLocation(
          latitude: 37.7749,  // 默认用户位置
          longitude: -122.4194,
        ),
        filterBar: FilterBar(
          distanceTextStyle: TextStyle(fontSize: 16),
          filterTextStyle: TextStyle(fontSize: 16),
        ),
        storeItemBuilder: (context, store) {
          return Card(
            child: ListTile(
              leading: Image.asset(store.image),
              title: Text(store.name),
              subtitle: Text(store.address),
              trailing: Icon(Icons.arrow_forward),
              onTap: () {
                // 打开商店详情页面
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => StoreDetailScreen(store: store),
                  ),
                );
              },
            ),
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          // 获取当前用户位置
          var position = await Geolocator.getCurrentPosition(
            desiredAccuracy: LocationAccuracy.high,
          );
          _controller.setUserLocation(
            UserLocation(
              latitude: position.latitude!,
              longitude: position.longitude!,
            ),
          );
        },
        tooltip: 'Get Current Location',
        child: Icon(Icons.location_on),
      ),
    );
  }
}

class StoreDetailScreen extends StatelessWidget {
  final Store store;

  StoreDetailScreen({required this.store});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(store.name),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Image.asset(store.image),
            SizedBox(height: 16),
            Text(store.address, style: TextStyle(fontSize: 18)),
            SizedBox(height: 8),
            Text('Phone: ${store.phoneNumber}'),
            SizedBox(height: 8),
            Text('Website: ${store.website}'),
            SizedBox(height: 8),
            Text('Email: ${store.email}'),
          ],
        ),
      ),
    );
  }
}

5. 添加权限

由于获取用户当前位置需要权限,你需要在AndroidManifest.xmlInfo.plist中添加必要的权限声明。

Android

AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

iOS

Info.plist中添加:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location always.</string>

6. 运行应用

现在,你可以运行你的Flutter应用,查看商店定位功能是否正常工作。

这个示例展示了如何使用store_locator插件来显示附近的商店,并允许用户获取当前位置以更新商店列表。你可以根据需要进一步自定义和扩展这个示例。

回到顶部