(Flutter) 釣魚資訊平台 - Day1 - 定位

閱讀時間約 10 分鐘
因為自己最近迷上了釣魚,但卻常常苦於不知道該去哪裡釣魚才能安全又有魚,因此想做個讓大家可以分享自己釣點以及釣況的App,讓大家都能找到適合自己的地方釣魚!
最近有新開一個部落格是在介紹Flutter相關的文章,大家可以去看看~

專案架構

專案架構可以參考我上一篇文章,這個專案我也是使用這個架構搭配GetX作為管理套件。

Pub.dev

Pub.dev提供了許多專門給Dart和Flutter使用的套件,如果有要實作的功能,可以先到這裡尋找有沒有別人已經做好的套件可以使用,可以省下許多麻煩,如果你有做好的套件也可以上傳到這裡供大家使用!

基本設定

Dart會找到你專案中的main()這個方法作為整個程式的起點,因此只能有一個main function,在你創建好專案後就會有基本的設定,不需要特別去調整。
接下來我們針對我們的App,做一些基本的設定
void main() async {
  await Firebase.initializeApp(); -> 確保建立Firebase相關的實例
  runZonedGuarded(() async {
    runApp(MyApp()); -> 啟動 App
  }, (Object error, StackTrace stack) async {
    // 這邊是錯誤處理,防止沒有被catch到的error, app會直接crash
    // 可以做一個dialog來提醒user 或是在此紀錄錯誤log 方便之後修正
  });
}
  • getPages 為整個app所有的畫面路徑設定
  • initialRoute 為app 進入的第一個畫面的路徑
  • initialBinding 是開啟app時會初始化的GetX Binding
  • 將原本的 MaterialApp 改為 GetMaterialApp,這樣就可以使用GetX來管理路徑了
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Fish Info',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: Routes.splashRoute, -> 第一個畫面的路徑
      getPages: Routes.routes,
      localizationsDelegates: const [
        DefaultCupertinoLocalizations.delegate, -> 之後說明用處
      ],
      initialBinding: GlobalBinding(),
    );
  }
}

路徑設定

這裡就是設定所有畫面的地方,以後有要新增畫面記得要回來這邊新增路徑跟GetPage,記得一定要使用binding來註冊GetXController,否則在某些特定情況下GetXController不會被正常初始化及釋放!
class Routes {
  Routes._();
  static const splashRoute = '/splash';
  static const homeRoute = '/home';
  static final List<GetPage> routes = [
    GetPage(name: splashRoute, page: () => const SplashPage(), binding: SplashBinding()),
    GetPage(name: homeRoute, page: () => const HomePage(), binding: HomeBinding()),
  ];
}

如何連結GetX Controller

只需要繼承Bindings並覆寫dependecies,在裡面初始化你想要的GetXController即可,如果需要多個相同種類的controller,可以新增tag的參數並在使用時代入參數即可,之後有機會再做詳細的說明。
如果不想要你的controller在頁面被移除時也跟著被移除,像是我們的GlobalController,可以在初始化時代入permanent參數為true即可。
class GlobalBinding extends Bindings {
  @override
  void dependencies() {
    Get.put<GlobalController>(GlobalController(), permanent: true);
  }
}

啟動畫面

在這個畫面我們要獲取使用者的位置,因此需要獲取權限才能去定位使用者,我們使用Geolocator這個套件來幫忙,根據不同的平台會有不同的設定需要先設定,大家可以點進去照著做就可以了!
我們創建一個GeoHelper class,裡面用來放我們Geo相關的code,方便我們之後重複使用。
class GeoHelper {
  GeoHelper._();
  static Future<Position> determinePosition() async {
    ...
  }
}
獲得地點的程式碼在Geolocator內有範例,大家可以去參考!

畫面

目前畫面還是空空如也,等到之後背景決定好之後再加上去~
class SplashPage extends StatelessWidget {
  const SplashPage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return const SizedBox();
  }
}

GetX Controller

我們會在這個class內處理所有的邏輯,late可以讓參數不用馬上賦予值,但是一定要確保他在被使用前被賦予值,否則程式會出現錯誤,目前沒有方法檢查變數是否已經被賦予值,因此在使用時要格外小心!
這邊我們會使用CameraPosition,需要先拿到Google Map的套件才會有這個model,可以先去安裝,我們在下個畫面會使用到。
可以直接在terminal到專案位置輸入 flutter pub add google_maps_flutter,就會自己安裝了,所有在pub.dev的套件都有這個功能,可以到每個套件的Installing內找到。
class SplashController extends GetxController {
  late CameraPosition initialCameraPosition;
  late bool isPermissionAllowed;
  @override
  void onInit() {
    GeoHelper.determinePosition().then((position) {
      // 成功得到使用者的位置資訊
      initialCameraPosition = CameraPosition(
        target: LatLng(position.latitude, position.longitude),
        zoom: Config.defaultCameraZoom,
      );
      isPermissionAllowed = true;
    }).catchError((_) {
      // 代表使用者拒絕提供位置資訊或是獲取資訊有錯誤,因此我們要給予一個預設的值
      initialCameraPosition = Config.defaultCameraPosition;
      isPermissionAllowed = true;
    }).whenComplete(() {
      // 不管有沒有錯誤最後都會進到這裡
      // 這裡我們要進到下一個畫面
      Get.offNamed(
        Routes.homeRoute,
        // 將我們在這裡得到的資訊傳到下一個頁面
        arguments: HomePageArgs(
          initialCameraPosition: initialCameraPosition,
          isPermissionAllowed: isPermissionAllowed,
        )
      );
    });
  }
}

GetX 路徑

GetX有提供許多轉換畫面的方法,根據不同的情境可以搭配使用。
  • Get.offNamed: 移除當前的畫面並進入到下一頁,因為我們不希望使用者再回到Splash畫面,因此將他移除,當然我們也可以透過WillPopScope來防止使用者透過Android back按鍵或是iPhone的向右滑回到上一頁,但因為我們也不需要保留這個頁面,所以選擇這個方法。
剩下的方法大家可以到GetX的網站去看,他有提供許多種語言的文件方便大家閱讀。
今天就先做到這裡,如果有任何問題、錯誤或是希望我介紹的主題都可以留言告訴我,謝謝!
3會員
2內容數
留言0
查看全部
發表第一個留言支持創作者!
貓俠的沙龍 的其他內容
如果你是剛入門Flutter的工程師,可以參考這篇文章,我會告訴大家自己常用的套件以及如何規劃檔案的分類!
如果你是剛入門Flutter的工程師,可以參考這篇文章,我會告訴大家自己常用的套件以及如何規劃檔案的分類!
你可能也想看
Google News 追蹤
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
Flutter is a powerful, open-source UI software development kit created by Google.
Thumbnail
解析成List List items=json.decode(jsonStr); print(items[0]["your_key"]); 解析成Map Map<String, dynamic> user = json.decode(json); print('${user['your_k
Thumbnail
這邊會使用WebSocketChannel去與http://www.websocket.org做連線。 連線 final channel = IOWebSocketChannel.connect('wss://echo.websocket.events'); 接收 StreamBui
Thumbnail
Dio是一個Dart Http請求庫,支援Restful API、FormData、攔截器、請求取消、Cookie管理、檔案上傳/下載、逾時等。 加入 dependencies: dio: ^x.x.x #请使用pub上的最新版本 使用 GET Response response;
Thumbnail
配置 idleTimeout:在httpClient請求結束後,會繼續保持連線,直到超過idleTimeout值才會關閉連接。 connectionTimeout:和伺服器建立連線逾時,如果超過connectionTimeout值則會拋出SocketException異常。 maxConnec
Thumbnail
我將休息、運動的概念引進給考生,一度讓老師覺得不妥,在我的視角:好的身體才有努力的本錢。
Thumbnail
1.項目介紹 Bitget 是領先世界的加密貨幣衍生品交易平台。立即在Bitget 購買比特幣和以太幣,開始您的加密交易之旅! 2.影片介紹 3.小礦工挖挖礦 所有社群連結 https://linktr.ee/TinyTinyMiner
Thumbnail
大學有很多活動、想做的事情攤在眼前,怎麼樣過濾篩選哪些事情能同時符合現實、成長以及興趣?
Thumbnail
藥師通常從廠商來函或是業務代表通知而取得藥品短缺訊息,民眾若想要掌握相關較完整訊息,可以至食藥署「藥品供應資訊平台」(食藥署首頁 > 業務專區 > 藥品 > 通報專區,網址: https://dsms.fda.gov.tw/)。
Thumbnail
理工至上似乎在另一群高薪人的眼中是「奴工」的代表。如果可能的選項都沒有不好,怎麼選?
Thumbnail
這個秋,Chill 嗨嗨!穿搭美美去賞楓,裝備款款去露營⋯⋯你的秋天怎麼過?秋日 To Do List 等你分享! 秋季全站徵文,我們準備了五個創作主題,參賽還有機會獲得「火烤兩用鍋」,一起來看看如何參加吧~
Thumbnail
美國總統大選只剩下三天, 我們觀察一整週民調與金融市場的變化(包含賭局), 到本週五下午3:00前為止, 誰是美國總統幾乎大概可以猜到60-70%的機率, 本篇文章就是以大選結局為主軸來討論近期甚至到未來四年美股可能的改變
Thumbnail
Faker昨天真的太扯了,中國主播王多多點評的話更是精妙,分享給各位 王多多的點評 「Faker是我們的處境,他是LPL永遠繞不開的一個人和話題,所以我們特別渴望在決賽跟他相遇,去直面我們的處境。 我們曾經稱他為最高的山,最長的河,以為山海就是盡頭,可是Faker用他28歲的年齡...
Thumbnail
Flutter is a powerful, open-source UI software development kit created by Google.
Thumbnail
解析成List List items=json.decode(jsonStr); print(items[0]["your_key"]); 解析成Map Map<String, dynamic> user = json.decode(json); print('${user['your_k
Thumbnail
這邊會使用WebSocketChannel去與http://www.websocket.org做連線。 連線 final channel = IOWebSocketChannel.connect('wss://echo.websocket.events'); 接收 StreamBui
Thumbnail
Dio是一個Dart Http請求庫,支援Restful API、FormData、攔截器、請求取消、Cookie管理、檔案上傳/下載、逾時等。 加入 dependencies: dio: ^x.x.x #请使用pub上的最新版本 使用 GET Response response;
Thumbnail
配置 idleTimeout:在httpClient請求結束後,會繼續保持連線,直到超過idleTimeout值才會關閉連接。 connectionTimeout:和伺服器建立連線逾時,如果超過connectionTimeout值則會拋出SocketException異常。 maxConnec
Thumbnail
我將休息、運動的概念引進給考生,一度讓老師覺得不妥,在我的視角:好的身體才有努力的本錢。
Thumbnail
1.項目介紹 Bitget 是領先世界的加密貨幣衍生品交易平台。立即在Bitget 購買比特幣和以太幣,開始您的加密交易之旅! 2.影片介紹 3.小礦工挖挖礦 所有社群連結 https://linktr.ee/TinyTinyMiner
Thumbnail
大學有很多活動、想做的事情攤在眼前,怎麼樣過濾篩選哪些事情能同時符合現實、成長以及興趣?
Thumbnail
藥師通常從廠商來函或是業務代表通知而取得藥品短缺訊息,民眾若想要掌握相關較完整訊息,可以至食藥署「藥品供應資訊平台」(食藥署首頁 > 業務專區 > 藥品 > 通報專區,網址: https://dsms.fda.gov.tw/)。
Thumbnail
理工至上似乎在另一群高薪人的眼中是「奴工」的代表。如果可能的選項都沒有不好,怎麼選?