فلاتر

آموزش مسیریابی با AutoRoute در فلاتر

زمانی که در حال توسعه یک اپلیکیشن فلاتر هستید با بزرگ و پیچیده تر شدن پروژه استفاده از مسیریابی به وسیله اسم یک ضرورت هست به همین دلیل آموزش امروز نحوه کار با پکیج AutoRoute می باشد..

برای اینکار نیاز به پکیج خاصی ندارید اما با استفاده از کتابخانه auto_route میتوانید اینکار در زمان کمتر و با امکانات بهتری انجام دهید.

پیاده سازی

در فایل pubspec کد زیر را وارد کنید.

auto_route: 0.6.7

همچنین dev_dependencies را نیز به شکل زیر اضافه کنید.

build_runner:
auto_route_generator: ^0.6.8

کد زیر را اجرا کنید.

flutter packages get

در ادامه نیاز داریم تا AndriodX را فعال کنیم.

به همین منظور فایل gradle.properties کد زیر را وارد کنید.

org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

کد نویسی و مسیریابی

برای شروع کد نویسی فایل جدیدی به اسم home_page ایجاد کنید.

در این صفحه سه دکمه قرار میدهیم که با کلیک کردن روی هرکدوم به یک صفحه مشخص منتقل خواهیم شد.

 Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                FlatButton(
                  padding: EdgeInsets.only(left: 20,right: 30),
                  color: Colors.cyan,
                  onPressed: (){
                    ExtendedNavigator.root.push(
                    Routes.firstPage,
                    arguments: FirstPageArguments(
                      info: "Hello Flutter Dev's",
                    ),
                  );
                  },
                  child: Text("First Page",style: TextStyle(color: Colors.black),),
                ),
                FlatButton(
                  color: Colors.tealAccent,
                  onPressed: (){
                    ExtendedNavigator.root.push(
                    Routes.secondPage,
                    arguments: SecondPageArguments(
                      name: "Flutter Dev's",
                      emp: 165,
                    ),
                  );
                    },
                  child: Text("Second Page",style: TextStyle(color: Colors.black)),
                ),
                FlatButton(
                  padding: EdgeInsets.only(left: 20,right: 30),
                  color: Colors.teal,
                  onPressed:(){
                    ExtendedNavigator.root.push(
                    Routes.thirdPage,
                    arguments: ThirdPageArguments(
                      name: "Flutter Dev's",
                      dsg: "Software Engineer",
                    ),
                  );},
                  child: Text("Third Page",style: TextStyle(color: Colors.black)),
                ),
              ],
            ),

فایلی به اسم first_page.dart میسازیم که مشخص کننده صفحه اول ما است.

در این کلاس یک متغیر به اسم info داریم که آن را دریافت میکنیم و نمایش میدهیم.

import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
  const FirstPage({
    Key key,
    @required this.info,
  }) : super(key: key);

  final String info;

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      backgroundColor: Colors.white70,
      appBar: AppBar(
          backgroundColor: Colors.black,
          title: Text("First Page"),
        ),
        body: SafeArea(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(info,style: TextStyle(fontSize: 22),),
              ],
            ),
          ),
        ),
    );
  }
}

صفحه دوم را به اسم second_page.dart میسازیم.

در صفحه دوم دو متغیر داریم به نام name از نوع رشته و یک متغیر عددی به نام emp که در صفحه هر دو را استفاده میکنیم.

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  const SecondPage({
    Key key,
    @required this.name,
    @required this.emp,
  }) : super(key: key);

  final String name;
  final int emp;

  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      backgroundColor: Colors.white70,
      appBar: AppBar(
          backgroundColor: Colors.black,
          title: Text("Second Page"),
        ),
        body: SafeArea(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text("Name : $name",
                    style: TextStyle(fontSize: 22),),
                Text("Employee : $emp",
                   style: TextStyle(fontSize: 22),),
              ],
            ),
          ),
        ),
    );
  }
}

صفحه بعدیمون به اسم third_page.dart است که دو متغیر از نوع رشته به اسم های name, dsg هستند.

import 'package:flutter/material.dart';

class ThirdPage extends StatelessWidget {
  const ThirdPage({
    Key key,
    @required this.name,
    @required this.dsg,
  }) : super(key: key);

  final String name;
  final String dsg;
  @override
  Widget build(BuildContext context) {
    return  Scaffold(
      backgroundColor: Colors.white70,
      appBar: AppBar(
        backgroundColor: Colors.black,
        title: Text("Third Page"),
      ),
      body: SafeArea(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Name : $name",style: TextStyle(fontSize: 22),),
              Text("Designation : $dsg",style: TextStyle(fontSize: 22),),
            ],
          ),
        ),
      ),
    );
  }
}

اما حالا نوبت بخش مسیریابی هست. فایل جدیدی به اسم router.dart ایجاد کنید. این کلاس کدهایی که برای مسیریابی لازم است را به وسیله پکیج AutoRoute تولید میکند.

کلاس مسیریابی را باید به وسیله انوتیشن AdaptiveAutoRouter مشخص کنیم تا کلاس های مختلف و به عنوان مسیر در قالب پارامتر قرار دهیم.

@AdaptiveAutoRouter(routes: <AutoRoute>[
  AutoRoute(page: HomePage, initial: true),
  AutoRoute(page: FirstPage),
  AutoRoute(page: SecondPage),
  AutoRoute(page: ThirdPage,),
])
class $FlutterRouter {}

در این کلاس یک لیست از نوع AutoRoute داریم که کلاس های ساخته شده را داخل آن قرار داده ایم.

در آخر باید توجه کنید که قبل از نام کلاس باید از علامت $ استفاده کنید. برای مثال FlutterRouter$ اینکار باعث میشه بعد از build شدن پروژه کدهای مورد نیاز ایجاد شوند.

برای اینکه کدهای مورد نیاز ساخته شوند از دستور زیر یکبار استفاده کنید تا پروژه بازسازی شود.

flutter packages pub run build_runner watch

بعد از اتمام این کار یک فایل به اسم router.gr.dart برای شما ایجاد میشود.

بخشی از کدهای این فایل شبیه به کد زیر است.

// GENERATED CODE - DO NOT MODIFY BY HAND

// **************************************************************************
// AutoRouteGenerator
// **************************************************************************

// ignore_for_file: public_member_api_docs

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

import '../pages/first_page.dart';
import '../pages/home_page.dart';
import '../pages/second_page.dart';
import '../pages/third_page.dart';

class Routes {
  static const String homePage = '/';
  static const String firstPage = '/first-page';
  static const String secondPage = '/second-page';
  static const String thirdPage = '/third-page';
  static const all = <String>{
    homePage,
    firstPage,
    secondPage,
    thirdPage,
  };
}

class FlutterRouter extends RouterBase {
  @override
  List<RouteDef> get routes => _routes;
  final _routes = <RouteDef>[
    RouteDef(Routes.homePage, page: HomePage),
    RouteDef(Routes.firstPage, page: FirstPage),
    RouteDef(Routes.secondPage, page: SecondPage),
    RouteDef(Routes.thirdPage, page: ThirdPage),
  ];
  @override
  Map<Type, AutoRouteFactory> get pagesMap => _pagesMap;
  final _pagesMap = <Type, AutoRouteFactory>{
    HomePage: (data) {
      return buildAdaptivePageRoute<dynamic>(
        builder: (context) => const HomePage(),
        settings: data,
      );
    },
    FirstPage: (data) {
      final args = data.getArgs<FirstPageArguments>(nullOk: false);
      return buildAdaptivePageRoute<dynamic>(
        builder: (context) => FirstPage(
          key: args.key,
          info: args.info,
        ),
        settings: data,
      );
    },
    SecondPage: (data) {
      final args = data.getArgs<SecondPageArguments>(nullOk: false);
      return buildAdaptivePageRoute<dynamic>(
        builder: (context) => SecondPage(
          key: args.key,
          name: args.name,
          emp: args.emp,
        ),
        settings: data,
      );
    },
    ThirdPage: (data) {
      final args = data.getArgs<ThirdPageArguments>(nullOk: false);
      return buildAdaptivePageRoute<dynamic>(
        builder: (context) => ThirdPage(
          key: args.key,
          name: args.name,
          dsg: args.dsg,
        ),
        settings: data,
      );
    },
  };
}

حالا نیاز داریم از کدهای ایجاد شده بتونیم در برنامه فلاتر خودمون استفاده کنیم.

برای اینکار وارد فایل main میشویم و به شکل زیر تغییرات را اضافه میکنیم.

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: ExtendedNavigator.builder(
        router: FlutterRouter(),
        initialRoute: Routes.homePage,
        builder: (_, navigator) => Theme(
          data: ThemeData.dark(),
          child: navigator,
        ),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

در بخش router کلاس مسیر خودمون که ساخته بودیم را مینویسیم و در بخش initialRoute اولین مسیری که میخواهیم بصورت پیش فرض نمایش داده شود را قرار میدهیم.

اما ما سه عدد دکمه داشتیم که میخواستیم با کلیک کردن روی آنها به یکی از این سه صفحه منتقل شویم.

برای انتقال به مسیر جدید از کلاس ExtendedNavigator استفاده میکنیم که اسم مسیر مورد نظر به آن پاس میدهیم.

در این تصویر مشاهده میکنید که برای رفتن به صفحه اول در دستور مورد نظر اسم صفحه را به شکل Routes.firesPage نوشتیم و در قسمت arguments هم میتوانیم پارامتر های مورد نظر را به صفحه ارسال کنیم.

همچنین برای رفتن به صفحه دوم نیز میتوانیم خیلی راحت به شکل زیر عمل کنیم.

در این مقاله بصورت خلاصه نحوه مسیریابی با استفاده از کتابخانه در فلاتر را آموزش دادیم که میتوانید با توجه به نیاز خودتون کدها را تغییر دهید.

اما این کتابخانه قابلیت های بیشتر دیگری نیز دارد که پیشنهاد میکنم مستندات صفحه آن را مطالعه کنید.

Hesam

View Comments

  • درصورتی که میشه از push و pop استفاده کرد دلیلد استفاده از route چیه؟

    • سلام
      روی پرفورمنس تاثیری نداره ولی استفاده از named routes به طور کلی باعث تمیزی کد می شود زمانی که تعداد صفحات زیادی داشته باشید این قابلیت بیشتر به چشم و کمک میکنه به برنامتون که یک کد ساختاریافته داشته باشید و تغییرات جدید و بتونید اعمال کنید.
      برای مثال اگر قصد داشته باشید یک پارامتر به constructor یک صفحه اضافه کنید باید داخل تمام صفحات دنبال کدهایی بگیرید که از push داخل آن استفاده کردید و تغییرات را اعمال کنید.

  • با سلام بسیار مفید بود البته کنی بزای من گنگ بود. مثلا دستوراتی کهباید میزدیم کحا وارد کنیم در ترمینال ویندوز؟ یا داخل اندروید استودیو خودش جا برای اجرای دستور داره؟

    و در مورد این اموزش این درسته که اپ های 2 صفحه ای و 20 صفحه ای را با هر دو روش مسیریابی میتوان انجام داد و صرفا بحث تمیز بودن کد هست؟ یا در روش pop push محدودیت داریم؟

    • سلام داخل ترمینال اندروید استودیو دستورات و وارد کنید.
      بله مشکلی نداره شما میتونید از روش عادی مسیریابی استفاده کنید بحث تمیزی کد هست.

Recent Posts

گیتهاب اکشن چیست؟ آموزش استفاده از گیتهاب اکشن در برنامه نویسی فلاتر

گیتهاب اکشن GitHub Actions یکی از ابزارهای گیتهاب است که به شما کمک می‌کنه تا…

4 روز ago

آموزش افزایش سرعت اجرای وب اپلیکیشن های فلاتر

اگر یک برنامه نویس فلاتر هستید و با از نسخه وب اپلیکیشن پروژتون استفاده میکنید…

4 هفته ago

آموزش جامع انتشار اپلیکیشن اندروید و فلاتر در فروشگاه گوگل پلی Google play

به عنوان یک برنامه نویس فلاتر یا اندروید بعد از اتمام پروسه طراحی اپلیکیشن نیاز…

2 ماه ago

دانلود سورس کد رابط کاربری اپلیکیشن فلاتر پروژه پادکست

طراحی رابط کاربری اپلیکیشن پادکست خود را با استفاده از این کیت توسعه UI/UX فلاتر…

2 ماه ago

فایربیس چیست؟ معرفی سرویس ابری Firebase و کاربردهای آن

فایربیس، پلتفرمی قدرتمند از شرکت گوگل برای توسعه و مدیریت برنامه‌های موبایل و وب است.…

3 ماه ago

آموزش پیاده سازی Method Channel در فلاتر + فیلم

فلاتر یک فریم ورک برنامه نویسی چندسکویی است که این امکان را برای برنامه نویس…

3 ماه ago