ورود و عضویت
0
سبد خرید شما خالی است
0
سبد خرید شما خالی است

آموزش کار با ویجت NavigationRail در فلاتر

0 دیدگاه

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

اما تغییرات و امکاناتی که تیم فلاتر ارائه میدهند به اندازه کافی جذابیت دارند که هر برنامه نویسی را وادار به امتحان کردن آنها بکنند.

در این مطلب قصد داریم راجب ویجت جدیدی که در نسخه Flutter 1.7 به نام NavigationRail معرفی شد صحبت کنیم.

NavigationRail چیست؟

اولین نسخه پایدار فلاتر در سال 2020 شامل ویژگی های بسیار جدیدی بود از بهینه شدن برنامه های نوشته شده تا معرفی ابزار های جدید.

اما جذاب ترین بخش آن معرفی کامپوننت جدید متریال دیزاین به نام NavigationRail بود که میتواند جایگزین BottomNavigationBar شود.

این ویجت در چپ یا راست صفحه به شکل عمودی قرار میگیرد و برای جا به جایی بین صفحات با فرگمنت های استفاده می شود.

برای درک بهتر میتونید تصاویر زیر را که توسط بعضی از طراحان تهیه شده است مشاهده کنید.

ساختار معمولی

از NavigationRail در داخل بدنه ویجت Scafold و معمولا انتها یا ابتدای Row  استفاده می شود.

در این حالت منوی ما و محتوای اصلی صفحه توسط یک خط عمودی جدا می شود.

همچنین برای ایجاد سایه و زیبا تر کردن طراحی میتونید از ویژگی elevation نیز در نویگشن ریل استفاده کنید.

آموزش انتخاب عکس از گالری در فلاتر

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

اموزش متریال دیزاین NavigationRail
دانلود فلاتر

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

Scaffold(
  body: Row(
    children: <Widget>[
      NavigationRail(
        selectedIndex: _selectedIndex,
        onDestinationSelected: (int index) {
          setState(() {
            _selectedIndex = index;
          });
        },
        labelType: NavigationRailLabelType.selected,
        destinations: [
          NavigationRailDestination(
            icon: Icon(Icons.favorite_border),
            selectedIcon: Icon(Icons.favorite),
            label: Text('First'),
          ),
          NavigationRailDestination(
            icon: Icon(Icons.bookmark_border),
            selectedIcon: Icon(Icons.book),
            label: Text('Second'),
          ),
          NavigationRailDestination(
            icon: Icon(Icons.star_border),
            selectedIcon: Icon(Icons.star),
            label: Text('Third'),
          ),
        ],
      ),
      VerticalDivider(thickness: 1, width: 1),
      // This is the main content.
      Expanded(
        child: Center(
          child: Text('selectedIndex: $_selectedIndex'),
        ),
      )
    ],
  ),
);

ویژگی های NavigationRail

برای اینکه بتونیم از هر ویجت استفاده کنیم باید با ویژگی و امکاناتی که دارد به طور کامل آشنا شویم.

اما قبل از بررسی ویژگی ها, یک کلاس هست که باید معرفی کنیم به اسم NavigationRailDestination.

کلاس NavigationRailDestination چیست؟

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

همچنین این کلاس دیتای مقصدی که قصد رفتن به آن دارید را نیز نگهداری میکند.

کلاس NavigationRailDestination شامل سه ویژگی است که باهم بررسی میکنیم.

  1. Icon: این ویژگی یک ویجت از نوع آیکون دریافت میکند و هیچوقت نباید null باشد
  2. selectedIcon: این ویژگی اختیاری هست و میتونید استفاده نکنید, برای زمانی که میخواید state آیکون انتخاب شده تغییر کند کاربرد دارد.
  3. label: این فیلد هم اجباری هست و باید یک ویجت تکست برای آن قرار دهید البته میتونید مشخص کنید که لیبل نمایش داده شود یا خیر.
کلاس NavigationRailDestination

یک آبجکت معمولی از کلاس NavigationRailDestination به شکل زیر می باشد.

NavigationRailDestination(
  icon: Icon(Icons.favorite_border),
  selectedIcon: Icon(Icons.favorite),
  label: Text('First'),
),

اما بریم سراغ ویژگی های کلاس NavigationRail که قرار بود بررسی کنیم.

  • destinations: این ویژگی یک لیستی از آبجکت های NavigationRailDestination دریافت میکند. حداقل اندازه لیست باید 2 باشد.
  • selectedIconTheme و unselectedIconTheme: با استفاده از این دو ویژگی میتونید برای حالت های انتخاب شده و غیر انتخابی آیکون ها تم تعریف کنید که شامل رنگ آیکون, اندازه و … می باشد.
  • selectedLabelTextStyle و unselectedLabelTextStyle: این مورد هم مثل ویژگی قبلی می باشد اما برای عنوان یا همون لیبل استفاده میشه و میتونی استایل های مختلف و برای دو حالت انتخابی و غیر انتخاب شده تعریف کنید.
  • labelType: این ویژگی شامل انتخاب از بین سه گزینه می باشد که حالت نمایش منو را در سمت چپ یا راست تعیین میکند. سه حالت شامل NavigationRailLabelType.none , NavigationRailLabelType.selected,NavigationRailLabelType.all می باشد که در تصویر زیر تفاوت آنها را به خوبی میبینید.
labelType
labelType
  • groupAlignment: از این ویژگی برای مشخص کردن محل قرار گیری آیتم ها استفاده میکنیم. که مقداری بین 1- تا 1 دریافت میکند. بصورت پیش فرض این مقدار 1- می باشد که به معنی قرار گیری آیتم ها در بالای صفحه است, مقدار 0 محل قرار گیری آیتم ها در وسط و 1 نیز در انتهای صفحه می باشد.
groupAlignment
groupAlignment
  • leading & trailing: این ویژگی دقیقا به همان شکلی که در دیگر ویجت ها مثل ListTile, AppBar وجود دارد کار میکند. در این ویژگی ما میتونیم هر ویجتی که میخوایم قرار بدیم, برای مثال در تصویر زیر یک Column تعریف کردیم و داخل آن دو ویجت دیگر قرار دادیم. اگر میخواهید ویجت به ابتدای آیتم ها اضافه شود باید از leading استفاده کنید.
leading & trailing
leading & trailing

  • onDestinationSelected: این متد زمانی که روی یکی از آیتم ها کلیک شود اجرا میشود.

با هم دیگه ویژگی های مهم NavigationRail و بررسی کردیم و برای جمع بندی با یک مثال کارمون و تموم میکنیم.

ابتدا پیش نمایش کاری که انجام میدهیم و در تصویر زیر مشاهده میکنید.

آموزش Flutter

برای طراحی منو صفحه بالا میتونید از کد زیر استفاده کنید.

import 'package:flutter/material.dart';

class ScreenOne extends StatefulWidget {
  ScreenOne({Key key}) : super(key: key);

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

class _ScreenOneState extends State<ScreenOne> {
  int _selectedIndex = 0;
  final padding = 8.0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff28292E),
      body: Row(
        children: <Widget>[
          NavigationRail(
            minWidth: 56.0,
            groupAlignment: 1.0,
            backgroundColor: Color(0xff2D3035),
            selectedIndex: _selectedIndex,
            onDestinationSelected: (int index) {
              setState(() {
                _selectedIndex = index;
              });
            },
            labelType: NavigationRailLabelType.all,
            leading: Column(
              children: <Widget>[
                SizedBox(
                  height: 8,
                ),
                Center(
                  child: CircleAvatar(
                    radius: 16,
                    backgroundImage: NetworkImage(
                        "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80"),
                  ),
                ),
                SizedBox(
                  height: 108,
                ),
                RotatedBox(
                  quarterTurns: -1,
                  child: IconButton(
                    icon: Icon(Icons.tune),
                    color: Color(0xffFCCFA8),
                    onPressed: () {},
                  ),
                )
              ],
            ),
            selectedLabelTextStyle: TextStyle(
              color: Color(0xffFCCFA8),
              fontSize: 13,
              letterSpacing: 0.8,
              decoration: TextDecoration.underline,
              decorationThickness: 2.0,
            ),
            unselectedLabelTextStyle: TextStyle(
              fontSize: 13,
              letterSpacing: 0.8,
            ),
            destinations: [
              buildRotatedTextRailDestination("Popular", padding),
              buildRotatedTextRailDestination("Favourites", padding),
              buildRotatedTextRailDestination("Inspiration", padding),
              buildRotatedTextRailDestination("All", padding),
            ],
          ),
          // This is the main content.
          ContentSpace(_selectedIndex)
        ],
      ),
    );
  }
}

NavigationRailDestination buildRotatedTextRailDestination(
    String text, double padding) {
  return NavigationRailDestination(
    icon: SizedBox.shrink(),
    label: Padding(
      padding: EdgeInsets.symmetric(vertical: padding),
      child: RotatedBox(
        quarterTurns: -1,
        child: Text(text),
      ),
    ),
  );
}

class ContentSpace extends StatelessWidget {
  final int _selectedIndex;

  ContentSpace(this._selectedIndex);

  final List<String> images = [
    "https://images.unsplash.com/photo-1524758631624-e2822e304c36?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80",
    "https://images.unsplash.com/photo-1493663284031-b7e3aefcae8e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80",
    "https://images.unsplash.com/photo-1538688525198-9b88f6f53126?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1267&q=80",
    "https://images.unsplash.com/photo-1513161455079-7dc1de15ef3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80",
    "https://images.unsplash.com/photo-1544457070-4cd773b4d71e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=843&q=80",
    "https://images.unsplash.com/photo-1532323544230-7191fd51bc1b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80",
    "https://images.unsplash.com/photo-1549488344-cbb6c34cf08b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80",
  ];

  final List<String> titles = [
    "Popular\nIdeas",
    "Favourites",
    "Inspiration\nIdeas",
    "All"
  ];

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Padding(
        padding: const EdgeInsets.fromLTRB(24, 8, 0, 0),
        child: MediaQuery.removePadding(
          removeTop: true,
          context: context,
          child: ListView(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: <Widget>[
                  IconButton(
                    icon: Icon(Icons.search),
                    onPressed: () {},
                  ),
                  IconButton(
                    icon: Icon(Icons.calendar_today),
                    onPressed: () {},
                  ),
                ],
              ),
              SizedBox(
                height: 24,
              ),
              Text(titles[_selectedIndex],
                  style: Theme.of(context).textTheme.headline4),
              SizedBox(
                height: 24,
              ),
              for (var i in images) ImageCard(i),
            ],
          ),
        ),
      ),
    );
  }
}

class ImageCard extends StatelessWidget {
  final uri;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: const EdgeInsets.fromLTRB(0, 0, 24, 24),
      child: Image.network(uri),
      clipBehavior: Clip.antiAliasWithSaveLayer,
      elevation: 0.0,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(16),
      ),
    );
  }

  const ImageCard(this.uri);
}

دیدگاهتان را بنویسید

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

Hesam
13 مه 2020
آموزش فارسی فلاتر
آموزش فارسی flutter