کلاس Navigation

تعداد بازدید ها : 1,093 بازدید
 کلاس Navigation

در طول اجرای یک برنامه بارها و بارها نیاز می شود که از نمایی (Screen) به نمای دیگر جابجا شده و مجدد برگردید . مدیریت جابجایی بین نماها توسط کلاس Navigation صورت می پذیرد . این کلاس در واقع پشته ای (Stack) از نماها ایجاد می کند و توسط push و pop ورود و خروج به این پشته را مدیریت می نماید .

روش اول : جابجایی با استفاده از دستور Navigator.push

قطعه کد زیر نمونه ای از جابجایی بین نماها به روش Navigator.push را نمایش می دهد :

import 'package:flutter/material.dart'; 

void main() => runApp(MaterialApp(debugShowCheckedModeBanner: false, home: MyHomeApp()));

class MyHomeApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Navigation Test'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.push(context, new MaterialPageRoute(builder: (context) {
              return MyPageTwo();
            }));
          },
          child: Text('برو صفحه دو'),
        ),
      ),
    );
  }
}

class MyPageTwo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Directionality(
      textDirection: TextDirection.rtl,
      child: Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          title: Row(
            children: <Widget>[
              IconButton(
                icon: Icon(Icons.arrow_back),
                onPressed: () => Navigator.pop(context),
              ),
              Text('صفحه دوم')
            ],
          ),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SizedBox(
                  width: 100,
                  height: 100,
                  child: Image.network(
                      'https://javareshkian.ir/wp-content/uploads/2020/03/javareshkian4.png')),
              Text('به صفحه دوم خوش آمدید'),
            ],
          ),
        ),
      ),
    );
  }
}

همانطور که در خط ۱۵ کد فوق قابل مشاهده است ، در هر کجا که لازم شد به نمای دیگری مراجعه نمایید می توانید از قطعه کد زیر استفاده نمایید :

onPressed: () {
   Navigator.push(
      context, 
      new MaterialPageRoute(
        builder: (context) {
           return MyPageTwo();
        }
      )
   );
}

در خط ۶ ، MyPageTwo نام ویجتی است که نمای صفحه ۲ ما را ایجاد می نماید . از آنجایی که ما در این لحظه در حال ایجاد یک شی از نوع MypageTwo هستیم به راحتی می توانید در سازنده کلاس هر مقداری که مد نظر دارید به صفحه ۲ پاس دهید .

می خوانم   Timer در دارت

خروجی کد فوق در تصویر زیر دیده می شود :

Navigation_Sample

دریافت اطلاعات از نمای صفحه ۲

جهت دریافت اطلاعات از نمای صفحه ۲ نیز به جای اینکه در رویداد onPressed مستقیما Navigator.push را فراخوانی کنید ، آن را به یک تابع از نوع async منتقل کرده و مقدار برگشتی از طرف Navigator.pop را به روش زیر دریافت نمایید :

navigateAndDisplaySomeMessage(BuildContext context, ChatData chatData) async{
  final ChatData result = await Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => SingleUserChat(userData: chatData))
  );

  Scaffold.of(context).showSnackBar(
    new SnackBar(content: new Text(result.userName),duration: Duration(seconds: 1),)
  );
}

در این مثال navigateAndDisplaySomeMessage نام دلخواهی است که ما برای تابع خود در نظر گرفته ایم . این تابع از نوع async تعریف شده تا قبل از فراخوانی Navigator.push بتوانیم از دستور await استفاده نماییم . این کار باعث می شود برنامه بدون از کار افتادن ، منتظر دریافت نتیجه از نمای صفحه ۲ بماند . به محض دریافت نتیجه از نمای صفحه ۲ ، اجرای کد از خط ۲ مربوط به final result عبور کرده و خط ۷ مربوط به Scaffold.of اجرا می شود و توسط ویجت SnackBar یک کادر حاوی متن در پایین صفحه نمایش داده می شود .

همانطور که در خط ۴ کد فوق قابل مشاهده است در لحظه مقدار دهی به MaterialPageRoute ما یک شی از نوع ChatData را به ویجت SingleUserChat (صفحه ۲) پاس داده ایم . در صفحه ۲ نیز در لحظه بازگشت از کد زیر استفاده شده است تا مجدد مقدار دریافتی (userData) به فرم اصلی برگردانده شود :

IconButton(
  icon: Icon(Icons.arrow_back),
  onPressed: () => Navigator.pop(context, userData),
)

روش دوم : جابجایی به روش Navigator.pushNamed

در صورتی که در لحظه جابجایی بین صفحات مقداری جابجا نمی شود ، می توانید از این روش جهت جابجایی استفاده نمایید . مزیت این روش این است که دستور مربوط به جابجایی بین تمام صفحات پروژه در یکجا ( خصوصیت routes مربوط به ویجت MaterialApp ) جمع آوری می شود و دسترسی به آنها ساده تر خواهد بود .

می خوانم   کپی کردن از یک لیست در لیست جدید

روش کار به این صورت است که ابتدا به روش زیر خصوصیت routes مربوط به ویجت MaterialApp را مقدار دهی می نمایید :

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'WhatsApp',
        routes: {
          '/setting' : (context) => new SettingPage(),
          '/singleChat' : (context) => new SingleUserChat(userData: null)
        },
        theme: ThemeData(
          fontFamily: 'Vazir',
          //primarySwatch: Colors.blue,
          primaryColor: Color(0xff075e54), // رنگ AppBar
          accentColor: Color(0xff075e54), // رنگ FloatingBottun
        ),
        home: Directionality(
          textDirection: TextDirection.rtl,
          child: Center(child: MyHomePage(text: 'واتساپ')),
        ));
  }
}

سپس در مرحله فراخوانی Navigator مطابق کد زیر عمل می نمایید :

onPressed: () {
  //print('Floating Click');
  Navigator.pushNamed(context, '/setting');
},

در این حالت فقط کافیست نام صفحه ای که در خصوصیت routes ویجت MaterialApp ثبت کرده اید توسط Navigator.pushNamed فراخوانی نمایید .

یک نکته مهم در رابطه با Routing

در صورت استفاده از خصوصیت route ویجت MaterialApp شما می توانید از خصوصیت home این ویجت صرف نظر کنید و مقدار آن را در یکی از route ها تعریف نمایید . به کد زیر توجه نمایید :

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'WhatsApp',
        initialRoute: '/splashscreen',  // تعریف روت شروع کننده
        routes: {
          '/' : (context) => Directionality(textDirection: TextDirection.rtl,child: Center(child: MyHomePage(text: 'واتساپ'))),
          '/splashscreen' : (context) => new SplashScreen(),
          '/setting' : (context) => new SettingPage(),
          '/singleChat' : (context) => new SingleUserChat(userData: null)
        },
        theme: ThemeData(
          fontFamily: 'Vazir',
          //primarySwatch: Colors.blue,
          primaryColor: Color(0xff075e54), // رنگ AppBar
          accentColor: Color(0xff075e54), // رنگ FloatingBottun
        ),
//        home: Directionality(
//          textDirection: TextDirection.rtl,
//          child: Center(child: MyHomePage(text: 'واتساپ')),
//        )
    );
  }
}

همانطور که در کد فوق قابل مشاهده است ، ما یک روت با مقدار ‘/’ تعریف کرده ایم که کار home را انجام می دهد ، همچنین توسط خصوصیت initialRoute نام روت شروع کننده برنامه را تعیین کرده ایم و به این وسیله به برنامه اعلام کردیم که از این اسکرین برنامه را شروع کند .

می خوانم   تعریف Listener

 

جهت کسب اطلاعات بیشتر از این آدرس به سایت اصلی فلاتر مراجعه نمایید .

امیدوارم این مطلب برای شما مفید باشد .

2+
محمدمجتبی جوارشکیان

محمدمجتبی جوارشکیان

من محمدمجتبی جوارشکیان ، کارشناس IT و فعال اجتماعی هستم و در حوزه معماری ، طراحی ، تحلیل گری ، مدلسازی و توسعه ی محیط های نرم افزاری فعالیت دارم. همانند سایر کارشناسان IT در تلاشم تا دنیا جای زیباتری برای زندگی باشد. بسیار خوشحال می شوم من را از انتقادات ، پیشنهادات و نظرات خود مطلع فرمایید. آدرس ایمیل : mjfakhr@yahoo.com

ارسال یک پاسخ

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

4 × 2 =