این مقاله یک درس “پیش نویس” از سری آینده در توسعه برنامه موبایل Flutter با استفاده از Laravel API در پشت است. پیش نیاز این درس این است که شما قبلاً Android Studio و همه ابزارهای مورد نیاز برای Flutter، و با نحوه راه اندازی/اجرای برنامه از آنجا آشنا هستید.


Flutter پیش فرض main.dart “سلام جهان” نیست

در Android Studio ، هنگامی که یک پروژه Flutter جدید ایجاد می کنید ، با این پروژه ایجاد می شود lib/main.dart فایلی که شامل اکثر ویژگی های اصلی است که برای توسعه برنامه در Flutter باید بدانید.

هنگامی که راه اندازی می شود ، یک برنامه ساده و زیبا ارائه می دهد که شمارنده شمارنده را در مرکز افزایش می دهد ، هر بار که روی دکمه بعلاوه در پایین کلیک می کنید:

با این حال ، درک آن برای تازه واردان بسیار پیچیده است: ویدجتهای بدون حالت/حالت ، نحوه عملکرد حالتها ، نحوه تعریف متغیرها و غیره. فقط به کد نگاه کنید – حتی با نظرات بسیار مفید ، درک همه چیز دشوار است:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // Try running your application with "flutter run". You'll see the
        // application has a blue toolbar. Then, without quitting the app, try
        // changing the primarySwatch below to Colors.green and then invoke
        // "hot reload" (press "r" in the console where you ran "flutter run",
        // or simply save your changes to "hot reload" in a Flutter IDE).
        // Notice that the counter didn't reset back to zero; the application
        // is not restarted.
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  // This widget is the home page of your application. It is stateful, meaning
  // that it has a State object (defined below) that contains fields that affect
  // how it looks.

  // This class is the configuration for the state. It holds the values (in this
  // case the title) provided by the parent (in this case the App widget) and
  // used by the build method of the State. Fields in a Widget subclass are
  // always marked "final".

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: Column(
          // Column is also a layout widget. It takes a list of children and
          // arranges them vertically. By default, it sizes itself to fit its
          // children horizontally, and tries to be as tall as its parent.
          //
          // Invoke "debug painting" (press "p" in the console, choose the
          // "Toggle Debug Paint" action from the Flutter Inspector in Android
          // Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
          // to see the wireframe for each widget.
          //
          // Column has various properties to control how it sizes itself and
          // how it positions its children. Here we use mainAxisAlignment to
          // center the children vertically; the main axis here is the vertical
          // axis because Columns are vertical (the cross axis would be
          // horizontal).
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

یک “سلام جهان” معمولی ساده نیست ، درست است؟

طرح B: واقع گرایانه “سلام جهان”

بنابراین ، به جای این مثال پیش فرض همه کاره ، بیایید یک مثال بسیار ساده تر را پیاده سازی کنیم-فقط یک صفحه ساده با مرکز سلام “Hello world”.

در اینجا کدی وجود دارد که می توانید به جای پیش فرض آن را کپی کنید lib/main.dart، همه محتویات آن را جایگزین می کند. در زیر ، آن را خط به خط توضیح خواهم داد:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: Scaffold(
        appBar: AppBar(
          title: Text('Welcome to Flutter'),
        ),
        body: Center(
          child: Text(
              'Hello World',
              style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold)
          ),
        ),
      ),
    );
  }
}

در حال حاضر ، این چیزی است که ما می توانیم با آن کار کنیم. بنابراین ، گام به گام.

import 'package:flutter/material.dart';

این خط به معنای وارد کردن یک کتابخانه Material Design است ، که کتابخانه پیش فرض Flutter است که همه چیز مورد نیاز ما را تأمین می کند طراحی متریال ویجت ها اطلاعات بیشتر در مورد ابزارک های زیر.

void main() => runApp(MyApp());

این خط تعریف کننده است اصلی () روشی که هنگام راه اندازی برنامه به طور خودکار اجرا می شود.

نحو مهم اینجاست => نماد ، این یک نحو کوتاه برای تابعی است که فقط یک خط دارد. گزینه طولانی تری برای نوشتن یک چیز وجود خواهد داشت:

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

همانطور که می بینید، runApp () این تنها کاری است که این تابع انجام می دهد ، بنابراین می توانیم آن را با نحو فلش کوتاه کنیم. در آینده ، شما این کار را با Flutter انجام خواهید داد ، بنابراین به خاطر سپردن آن بسیار مهم است.

بعد، runApp (MyApp ()) به ویجت اصلی که برای اجرای برنامه راه اندازی می شود اشاره می کند. حالا ، بیایید ببینیم داخل آن چیست MyApp () ویجت

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // ... will discuss internals a bit later
    );
  }
}

خوب ، در اینجا ما به مهمترین موضوع Flutter می رسیم: ابزارکبه در اصل ، همه عناصری که می توانید در صفحه برنامه مشاهده کنید ابزارک هستند: دکمه ها ، زمینه های متن ، برچسب ها و غیره.

اما انواع دیگری از ویجت ها برای مقاصد مختلف وجود دارد ، مواردی مانند Container ، Column یا حتی Padding ، برای سبک بندی تمام عناصر دقیقاً همانطور که می خواهید.

در این مورد ، در اینجا می توانید “جهانی” را مشاهده کنید ویجت بدون کشور کلاس مورد استفاده قرار می گیرد و توسط کلاس اصلی شما گسترش می یابد MyAppبه چیزی که ما در آن استفاده می کنیم runApp (MyApp ()) به عنوان یک پارامتر

بی تابعیت ویجت به این معنی است که هیچ گونه رفتار پویایی روی صفحه اتفاق نمی افتد ، بنابراین هیچ متغیر یا داده ای پس از کلیک روی دکمه تغییر نمی کند. در مورد ما ، این فقط یک متن “سلام جهان” خواهد بود. ما در درس های بعدی به نوع دیگر ، Stateful Widget ها می پردازیم.

بنابراین ، ویجت برنامه اصلی شما به احتمال زیاد یک ویجت بدون حالت را گسترش می دهد و در داخل شما باید یک ویجت اضافه کنید ساختن() روش ، که توضیح می دهد چه چیزی در داخل ویجت وجود دارد. قبل از آن ، شما اضافه کنید @override keyword که به این معنی است که شما متدی را که قبلاً در کلاس والد وجود دارد ، نادیده می گیرید.

بازگشت از ساختن() روش باید یک نوع باشد ویجت، و روش ساختن() پارامتر مورد نیاز از نوع را می پذیرد BuildContext – حتی اگر در واقع از آن متغیر در داخل استفاده نمی کنید ، باز هم باید آن را به عنوان یک پارامتر داشته باشید.

روش ساختن() یک ویجت به نام باز می گرداند MaterialAppبه می توانید توضیحات مربوط به آن را در اسناد رسمی ویجت Flutter، اما در حال حاضر تنها چیزی که باید بدانید این است که یک ویجت از کتابخانه Material Design است (به یاد داشته باشید ، یکی از مواردی که ما در اولین خط قرار دادیم).

ویجت MaterialApp: آنچه در داخل است

بیایید عمیق تر به این کد بپردازیم:

return MaterialApp(
  title: 'Welcome to Flutter',
  home: Scaffold(
    appBar: AppBar(
      title: Text('Welcome to Flutter'),
    ),
    body: Center(
      child: Text(
          'Hello World',
          style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold)
      ),
    ),
  ),
);

در اینجا چند اتفاق در حال رخ دادن است. نکته اصلی این است که همانطور که از ویجت استفاده می کنید ، مانند MaterialApp، پارامترهای آن را به صورت جفت کلید: value جدا شده با کاما ارائه می کنید. هر ویجت دارای مجموعه ای از پارامترهای ممکن است ، بنابراین شما باید از اسناد استفاده کنید ، و همچنین Android Studio به شما کمک می کند و به برخی از آنها اشاره می کند.

مثلا، MateralApp ویجت ، در میان پارامترهای دیگر ، دارد عنوان و خانهبه اگر نقل قول کنیم مستندات رسمی

– عنوان: توضیحات یک خطی که دستگاه برای شناسایی برنامه برای کاربر استفاده می کند. قابل مشاهده نیست ، فقط یک عنوان سیستم است.
خانه: ویجت مسیر پیش فرض برنامه. در مورد ما ، ما فقط یک “صفحه” خواهیم داشت ، بنابراین آن را بصورت داخلی تعریف می کنیم ، بعداً یک برنامه پیچیده تر خواهیم داشت ، بنابراین بسته به اینکه کاربر وارد سیستم شده است یا خیر ، صفحه اصلی را به صورت پویا تعریف می کنیم.

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

بنابراین در اینجا ما در نهایت بصری می شویم: ویجت داربست دارای ویژگی هایی مانند است appBar، بدن، bottomNavigationBar و دیگران.

در مورد ما ، ما از دو مورد استفاده می کنیم: appBar و بدنبه

اموال appBar منتظر ویجت است (ببینید ، همه چیز در Flutter یک ویجت است) از نوع AppBarبه باز هم ، دارای خواص مختلفی است ، اما برای مورد ما ، ما فقط از یکی استفاده می کنیم: عنوانبه

برای عنوان ، ما برمی گردیم … حدس بزنید … یک ویجت! بله ، حتی یک متن ساده یک ویجت است ، متن کلاس، که متن واقعی را می پذیرد (به Flutter خوش آمدید) ، و به طور اختیاری ویژگی های بیشتری – ما در یک دقیقه ، با مثال Text دوم ، به آن خواهیم رسید.

در حال حاضر ، دومین ویژگی ویجت Scaffold است بدنبه در حال بازگشت است ، غافلگیری غافلگیرکننده … یک ویجت. در این مثال ، من a را انتخاب کرده ام مرکز ویجت ، توضیح داده شده است در اسناد رسمی به عنوان “ویجتی که کودک خود را در درون خود متمرکز می کند”

خوب ، بنابراین اکنون ما یک ویجت داریم که دارای آن است فرزندان؟ بله ، در واقع ، در واقع ممکن است قبلاً متوجه شده باشید که تمام ساختار هر صفحه Flutter درختی از ویدجت ها – والدین و فرزندان است. در برخی از ویدجتها ، ویژگی دقیقاً چنین نامیده می شود: کودکبه و قبل از اینکه بپرسید ، بله ، انتظار یک ویجت را دارد. ما از همان استفاده خواهیم کرد متن ویجت ، مانند عنوان ، اما این بار – با پارامتر دوم سبک:

child: Text(
    'Hello World',
    style: TextStyle(fontSize: 28, fontWeight: FontWeight.bold)
),

ارزش سبک پارامتر ممکن است بسیار متفاوت باشد ، اما برای این مثال من انتخاب کرده ام TextStyle، که ممکن است پارامترهای زیادی را نیز بپذیرد – مستندات را ببینید و به عنوان یک تکلیف با کلیدها و ارزش های خود بازی کنید.

برای اندازه انتخاب شده من 28 و فونت پررنگ ، به نظر می رسد – بیایید دوباره به نتیجه نهایی نگاه کنیم:

بنابراین ، این تمام است ، شما اولین برنامه ساده تلفن همراه ثابت را با Flutter ایجاد کرده اید و امیدوارم ساختار آن را درک کرده باشید.

در مرحله بعد ، به ویجت های بیشتر و ویژگی های آنها می پردازید ، تا برنامه خود را دقیقاً همانطور که می خواهید تنظیم کنید و در آینده – برنامه خود را پویا کنید ، با ویدجت Stateful ، دکمه ها ، متغیرها و تبادل داده ها با API خارجی.