۱. مقدمه
| کامپوننتهای متریال (MDC) به توسعهدهندگان در پیادهسازی طراحی متریال کمک میکنند. MDC که توسط تیمی از مهندسان و طراحان UX در گوگل ایجاد شده است، دهها کامپوننت رابط کاربری زیبا و کاربردی را ارائه میدهد و برای اندروید، iOS، وب و Flutter.material.io/develop در دسترس است. |
اکنون میتوانید از Material Flutter برای سفارشیسازی سبک متمایز برنامههای خود بیش از هر زمان دیگری استفاده کنید. توسعه اخیر Material Design به طراحان و توسعهدهندگان انعطافپذیری بیشتری برای بیان برند محصولشان میدهد.
در codelabs MDC-101 و MDC-102، شما از Material Flutter برای ساخت اصول اولیه یک برنامه به نام Shrine ، یک برنامه تجارت الکترونیک که لباس و کالاهای خانگی میفروشد، استفاده کردید. این برنامه شامل یک جریان کاربری است که با یک صفحه ورود شروع میشود، سپس کاربر را به صفحه اصلی میبرد که محصولات را نمایش میدهد.
آنچه خواهید ساخت
در این آزمایشگاه کد، شما برنامه Shrine را با استفاده از موارد زیر سفارشیسازی خواهید کرد:
- رنگ
- تایپوگرافی
- ارتفاع
- شکل
- طرح بندی
اندروید | آیاواس |
|
|
|
|
اجزا و زیرسیستمهای Flutter متریال در این آزمایشگاه کد
- تمها
- تایپوگرافی
- ارتفاع
- فهرست تصاویر
سطح تجربه خود را در توسعه فلاتر چگونه ارزیابی میکنید؟
۲. محیط توسعه فلاتر خود را تنظیم کنید
برای تکمیل این آزمایشگاه به دو نرمافزار نیاز دارید - SDK فلاتر و یک ویرایشگر .
شما میتوانید codelab را با استفاده از هر یک از این دستگاهها اجرا کنید:
- یک دستگاه فیزیکی اندروید یا iOS که به رایانه شما متصل شده و روی حالت توسعهدهنده (Developer mode) تنظیم شده باشد.
- شبیهساز iOS (نیاز به نصب ابزارهای Xcode دارد).
- شبیهساز اندروید (نیاز به راهاندازی در اندروید استودیو دارد).
- یک مرورگر (برای اشکالزدایی، کروم مورد نیاز است).
- به عنوان یک برنامه دسکتاپ ویندوز ، لینوکس یا macOS . شما باید روی پلتفرمی که قصد استقرار آن را دارید، توسعه دهید. بنابراین، اگر میخواهید یک برنامه دسکتاپ ویندوز توسعه دهید، باید روی ویندوز توسعه دهید تا به زنجیره ساخت مناسب دسترسی داشته باشید. الزامات خاص سیستم عامل وجود دارد که به تفصیل در docs.flutter.dev/desktop پوشش داده شده است.
۳. اپلیکیشن شروع کدلب را دانلود کنید
ادامه از MDC-102؟
اگر MDC-102 را تکمیل کردهاید، کد شما باید برای استفاده در این آزمایشگاه کد آماده باشد. به مرحله بعدی بروید: تغییر رنگها .
از صفر شروع کردن؟
اپلیکیشن استارتر codelab را دانلود کنید
برنامهی آغازین در دایرکتوری material-components-flutter-codelabs-103-starter_and_102-complete/mdc_100_series قرار دارد.
... یا آن را از گیتهاب کلون کنید
برای کپی کردن این codelab از گیتهاب، دستورات زیر را اجرا کنید:
git clone https://github.com/material-components/material-components-flutter-codelabs.git cd material-components-flutter-codelabs/mdc_100_series git checkout 103-starter_and_102-complete
پروژه را باز کنید و برنامه را اجرا کنید
- پروژه را در ویرایشگر دلخواه خود باز کنید.
- دستورالعملهای «اجرای برنامه» را در بخش «شروع به کار: تست درایو » برای ویرایشگر انتخابی خود دنبال کنید.
موفقیت! شما باید صفحه ورود به سیستم Shrine از codelabs قبلی را روی دستگاه خود ببینید.
اندروید | آیاواس |
|
|
برای مشاهده صفحه محصول، روی «بعدی» کلیک کنید.
اندروید | آیاواس |
|
|
۴. رنگها را تغییر دهید
یک طرح رنگی ایجاد شده است که نمایانگر برند Shrine است و طراح میخواهد شما آن طرح رنگی را در سراسر برنامه Shrine پیادهسازی کنید.
برای شروع، بیایید آن رنگها را به پروژه خود وارد کنیم.
Create colors.dart
یک فایل دارت جدید در lib به نام colors.dart ایجاد کنید. material.dart را وارد کنید و مقادیر const Color را به آن اضافه کنید:
import 'package:flutter/material.dart';
const kShrinePink50 = Color(0xFFFEEAE6);
const kShrinePink100 = Color(0xFFFEDBD0);
const kShrinePink300 = Color(0xFFFBB8AC);
const kShrinePink400 = Color(0xFFEAA4A4);
const kShrineBrown900 = Color(0xFF442B2D);
const kShrineErrorRed = Color(0xFFC5032B);
const kShrineSurfaceWhite = Color(0xFFFFFBFA);
const kShrineBackgroundWhite = Colors.white;
پالت رنگ سفارشی
این تم رنگی توسط یک طراح با رنگهای سفارشی (که در تصویر زیر نشان داده شده است) ایجاد شده است. این تم شامل رنگهایی است که از برند Shrine انتخاب شده و در ویرایشگر تم متریال اعمال شدهاند، که آنها را گسترش داده تا یک پالت کاملتر ایجاد کند. (این رنگها از پالتهای رنگی متریال ۲۰۱۴ نیستند.)
ویرایشگر تم متریال، آنها را در سایههایی با برچسب عددی سازماندهی کرده است، از جمله برچسبهای ۵۰، ۱۰۰، ۲۰۰، .... تا ۹۰۰ از هر رنگ. Shrine فقط از سایههای ۵۰، ۱۰۰ و ۳۰۰ از نمونه صورتی و ۹۰۰ از نمونه قهوهای استفاده میکند.


هر پارامتر رنگی یک ویجت به رنگی از این طرحها نگاشت میشود. برای مثال، رنگ تزئینات یک فیلد متنی هنگام دریافت فعال ورودی باید رنگ اصلی قالب باشد. اگر آن رنگ در دسترس نیست (به راحتی در پسزمینه دیده میشود)، از رنگ دیگری استفاده کنید.
حالا که رنگهای مورد نظرمان را داریم، میتوانیم آنها را به رابط کاربری اعمال کنیم. این کار را با تنظیم مقادیر ویجت ThemeData که به نمونه MaterialApp در بالای سلسله مراتب ویجتها اعمال میکنیم، انجام خواهیم داد.
سفارشیسازی ThemeData.light()
فلاتر شامل چند تم داخلی است. تم روشن یکی از آنهاست. به جای اینکه یک ویجت ThemeData را از ابتدا بسازیم، تم روشن را کپی میکنیم و مقادیر آن را تغییر میدهیم تا برای برنامه خود سفارشیسازی کنیم.
بیایید colors.dart در app.dart.
import 'colors.dart';
سپس کد زیر را به app.dart خارج از محدوده کلاس ShrineApp اضافه کنید:
// TODO: Build a Shrine Theme (103)
final ThemeData _kShrineTheme = _buildShrineTheme();
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light(useMaterial3: true);
return base.copyWith(
colorScheme: base.colorScheme.copyWith(
primary: kShrinePink100,
onPrimary: kShrineBrown900,
secondary: kShrineBrown900,
error: kShrineErrorRed,
),
// TODO: Add the text themes (103)
// TODO: Decorate the inputs (103)
);
}
حالا، در انتهای تابع build() مربوط به ShrineApp (در ویجت MaterialApp) مقدار theme: را به عنوان تم جدید خود تنظیم کنید:
// TODO: Customize the theme (103)
theme: _kShrineTheme, // New code
پروژه خود را ذخیره کنید. صفحه ورود شما اکنون باید به این شکل باشد:
اندروید | آیاواس |
|
|
۵. اصلاح تایپوگرافی و سبکهای برچسب
علاوه بر تغییرات رنگ، طراح تایپوگرافی خاصی را نیز برای استفاده در اختیار ما قرار داده است. ThemeData فلاتر شامل ۳ تم متنی است. هر تم متنی مجموعهای از سبکهای متنی مانند "headline" و "title" است. ما از چند سبک برای برنامه خود استفاده خواهیم کرد و برخی از مقادیر را تغییر خواهیم داد.
سفارشیسازی تم متن
برای وارد کردن فونتها به پروژه، آنها باید به فایل pubspec.yaml اضافه شوند.
در pubspec.yaml، بلافاصله پس از تگ flutter: کد زیر را اضافه کنید:
# TODO: Insert Fonts (103)
fonts:
- family: Rubik
fonts:
- asset: fonts/Rubik-Regular.ttf
- asset: fonts/Rubik-Medium.ttf
weight: 500
حالا میتوانید به فونت روبیک دسترسی داشته باشید و از آن استفاده کنید.
عیبیابی فایل pubspec
اگر تعریف بالا را کپی و پیست کنید، ممکن است در اجرای pub get با خطا مواجه شوید. اگر با خطا مواجه شدید، با حذف فاصلهی خالی ابتدای خط و جایگزینی آن با فاصله با استفاده از تورفتگی ۲ فاصله شروع کنید. (دو فاصله قبل از
fonts:
، چهار فاصله قبل از
family: Rubik
، و غیره.)
اگر با عبارت Mapping values are not allowed here مواجه شدید، میزان تورفتگی خطی که مشکل دارد و همچنین میزان تورفتگی خطوط بالای آن را بررسی کنید.
در login.dart ، کد زیر را درون Column() تغییر دهید:
Column(
children: <Widget>[
Image.asset('assets/diamond.png'),
const SizedBox(height: 16.0),
Text(
'SHRINE',
style: Theme.of(context).textTheme.headlineSmall,
),
],
)
در app.dart ، کد زیر را بعد از _buildShrineTheme() اضافه کنید:
// TODO: Build a Shrine Text Theme (103)
TextTheme _buildShrineTextTheme(TextTheme base) {
return base
.copyWith(
headlineSmall: base.headlineSmall!.copyWith(
fontWeight: FontWeight.w500,
),
titleLarge: base.titleLarge!.copyWith(
fontSize: 18.0,
),
bodySmall: base.bodySmall!.copyWith(
fontWeight: FontWeight.w400,
fontSize: 14.0,
),
bodyLarge: base.bodyLarge!.copyWith(
fontWeight: FontWeight.w500,
fontSize: 16.0,
),
)
.apply(
fontFamily: 'Rubik',
displayColor: kShrineBrown900,
bodyColor: kShrineBrown900,
);
}
این یک TextTheme میگیرد و نحوه نمایش تیترها، عنوانها و زیرنویسها را تغییر میدهد.
اعمال fontFamily به این روش، تغییرات را فقط روی مقادیر مقیاس تایپوگرافی مشخص شده در copyWith() (headline، title، caption) اعمال میکند.
برای برخی از فونتها، ما یک fontWeight سفارشی با گامهای ۱۰۰ تایی تنظیم میکنیم: w500 (وزن ۵۰۰) مربوط به medium و w400 مربوط به regular است.
از تمهای متنی جدید استفاده کنید
بعد از خطا، تمهای زیر را به _buildShrineTheme اضافه کنید:
// TODO: Add the text themes (103)
textTheme: _buildShrineTextTheme(base.textTheme),
textSelectionTheme: const TextSelectionThemeData(
selectionColor: kShrinePink100,
),
پروژه خود را ذخیره کنید. این بار، برنامه را نیز مجدداً راهاندازی کنید (که به عنوان راهاندازی مجدد سریع شناخته میشود)، زیرا فونتها را تغییر دادهایم.
اندروید | آیاواس |
|
|
متنهای صفحه ورود و صفحه اصلی متفاوت به نظر میرسند—بعضی از متنها از فونت Rubik استفاده میکنند و برخی دیگر به جای سیاه یا سفید، به رنگ قهوهای نمایش داده میشوند. آیکونها نیز به رنگ قهوهای نمایش داده میشوند.
کوچک کردن متن
برچسبها خیلی بزرگ هستند.
در home.dart ، children: از داخلیترین ستون را تغییر دهید:
// TODO: Change innermost Column (103)
children: <Widget>[
// TODO: Handle overflowing labels (103)
Text(
product.name,
style: theme.textTheme.button,
softWrap: false,
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
const SizedBox(height: 4.0),
Text(
formatter.format(product.price),
style: theme.textTheme.bodySmall,
),
// End new code
],
متن را در مرکز قرار داده و رها کنید
ما میخواهیم برچسبها را در مرکز قرار دهیم و متن را به جای پایین هر تصویر، در پایین هر کارت تراز کنیم.
برچسبها را به انتهای (پایین) محور اصلی منتقل کنید و آنها را به صورت وسطچین تنظیم کنید::
// TODO: Align labels to the bottom and center (103)
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
پروژه خود را ذخیره کنید.
اندروید | آیاواس |
|
|
این خیلی بهتر به نظر میرسد.
زمینهبندی فیلدهای متنی
همچنین میتوانید با استفاده از InputDecorationTheme، تزیینات روی فیلدهای متنی را قالببندی کنید.
در app.dart ، در متد _buildShrineTheme() ، مقدار inputDecorationTheme: را مشخص کنید:
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
),
در حال حاضر، فیلدهای متنی دارای یک تزئین filled هستند. بیایید آن را حذف کنیم. حذف filled و مشخص کردن inputDecorationTheme به فیلدهای متنی سبک outline میدهد.
در login.dart ، مقادیر filled: true را حذف کنید:
// Remove filled: true values (103)
TextField(
controller: _usernameController,
decoration: const InputDecoration(
// Removed filled: true
labelText: 'Username',
),
),
const SizedBox(height: 12.0),
TextField(
controller: _passwordController,
decoration: const InputDecoration(
// Removed filled: true
labelText: 'Password',
),
obscureText: true,
),
راهاندازی مجدد سریع. صفحه ورود شما باید وقتی فیلد نام کاربری فعال است (وقتی در آن تایپ میکنید) به این شکل باشد:
اندروید | آیاواس |
|
|
در یک فیلد متنی تایپ کنید - حاشیهها و برچسبهای شناور به رنگ اصلی نمایش داده میشوند. اما ما نمیتوانیم آن را به راحتی ببینیم. برای افرادی که در تشخیص پیکسلهایی که کنتراست رنگی کافی ندارند مشکل دارند، قابل دسترسی نیست. (برای اطلاعات بیشتر، به مقاله «رنگ و دسترسیپذیری دستورالعملهای مواد» مراجعه کنید.)
در app.dart ، زیر inputDecorationTheme: یک focusedBorder: تعیین کنید:
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
),
سپس، یک floatingLabelStyle: زیر inputDecorationTheme: تعیین کنید:
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
floatingLabelStyle: TextStyle(
color: kShrineBrown900,
),
),
در نهایت، بیایید دکمه لغو را طوری تنظیم کنیم که برای افزایش کنتراست، به جای رنگ اصلی، از رنگ ثانویه استفاده کند.
TextButton(
child: const Text('CANCEL'),
onPressed: () {
_usernameController.clear();
_passwordController.clear();
},
style: TextButton.styleFrom(
primary: Theme.of(context).colorScheme.secondary,
),
),
پروژه خود را ذخیره کنید.
اندروید | آیاواس |
|
|
۶. تنظیم ارتفاع
حالا که صفحه را با رنگ و تایپوگرافی خاصی که با Shrine مطابقت دارد، استایلدهی کردهاید، بیایید ارتفاع (elevation) را تنظیم کنیم.
تغییر ارتفاع دکمه NEXT
ارتفاع پیشفرض برای یک ElevatedButton برابر با ۲ است. بیایید آن را بالاتر ببریم.
در login.dart ، یک مقدار style: به NEXT ElevatedButton اضافه کنید:
ElevatedButton(
child: const Text('NEXT'),
onPressed: () {
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
foregroundColor: kShrineBrown900,
backgroundColor: kShrinePink100,
elevation: 8.0,
),
),
پروژه خود را ذخیره کنید.
اندروید | آیاواس |
|
|
تنظیم ارتفاع کارت
در حال حاضر، کارتها روی یک سطح سفید در کنار نوار ناوبری سایت قرار دارند.
در home.dart ، مقدار elevation: را به Cards اضافه کنید:
// TODO: Adjust card heights (103)
elevation: 0.0,
Save the project.
اندروید | آیاواس |
|
|
سایه زیر کارتها را حذف کردهاید.
۷. شکل اضافه کنید
Shrine سبک هندسی جالبی دارد و عناصر آن به شکل هشت ضلعی یا مستطیلی تعریف میشوند. بیایید این سبک هندسی را در کارتهای صفحه اصلی و فیلدهای متنی و دکمههای صفحه ورود پیادهسازی کنیم.
شکل فیلدهای متنی را در صفحه ورود تغییر دهید
در app.dart ، فایل زیر را وارد کنید:
import 'supplemental/cut_corners_border.dart';
همچنان که در app.dart ، تم تزئین فیلد متن را برای استفاده از حاشیه برشخورده تغییر دهید:
// TODO: Decorate the inputs (103)
inputDecorationTheme: const InputDecorationTheme(
border: CutCornersBorder(),
focusedBorder: CutCornersBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrineBrown900,
),
),
floatingLabelStyle: TextStyle(
color: kShrineBrown900,
),
),
تغییر شکل دکمهها در صفحه ورود
در login.dart ، یک حاشیه مستطیلی اریب به دکمه CANCEL اضافه کنید:
TextButton(
child: const Text('CANCEL'),
onPressed: () {
_usernameController.clear();
_passwordController.clear();
},
style: TextButton.styleFrom(
foregroundColor: kShrineBrown900,
shape: const BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0)),
),
),
),
دکمهی متن (TextButton) هیچ شکل قابل مشاهدهای ندارد، پس چرا باید یک شکل حاشیهای به آن اضافه کنیم؟ تا انیمیشن موجدار هنگام لمس شدن به همان شکل محدود شود.
حالا همین شکل را به دکمه NEXT اضافه کنید:
ElevatedButton(
child: const Text('NEXT'),
onPressed: () {
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
foregroundColor: kShrineBrown900,
backgroundColor: kShrinePink100,
elevation: 8.0,
shape: const BeveledRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(7.0)),
),
),
),
برای تغییر شکل همه دکمهها، میتوانیم elevatedButtonTheme یا textButtonTheme در app.dart نیز استفاده کنیم. این به عنوان یک چالش برای یادگیرنده باقی میماند!
راهاندازی مجدد سریع (هات ریاستارت).
اندروید | آیاواس |
|
|
۸. طرحبندی را تغییر دهید
در مرحله بعد، بیایید طرحبندی را تغییر دهیم تا کارتها را با نسبتهای ابعاد و اندازههای مختلف نشان دهیم، به طوری که هر کارت از بقیه متمایز به نظر برسد.
جایگزینی GridView با AsymmetricView
ما قبلاً فایلهای مربوط به طرحبندی نامتقارن را نوشتهایم.
در home.dart ، دستور زیر را وارد کنید:
import 'supplemental/asymmetric_view.dart';
_buildGridCards را حذف و body را جایگزین کنید:
body: AsymmetricView(
products: ProductsRepository.loadProducts(Category.all),
),
پروژه را ذخیره کنید.
اندروید | آیاواس |
|
|
اکنون محصولات به صورت افقی در یک الگوی الهام گرفته از بافت، اسکرول میشوند.
۹. یک قالب دیگر را امتحان کنید (اختیاری)
رنگ، راهی قدرتمند برای بیان برند شماست و یک تغییر کوچک در رنگ میتواند تأثیر زیادی بر تجربه کاربری شما داشته باشد. برای آزمایش این موضوع، بیایید ببینیم اگر طرح رنگی برند کمی متفاوت بود، Shrine چگونه به نظر میرسید.
اصلاح رنگها
در colors.dart ، رنگ زیر را اضافه کنید:
const kShrinePurple = Color(0xFF5D1049);
در app.dart ، تابع _buildShrineTheme() را به صورت زیر تغییر دهید:
ThemeData _buildShrineTheme() {
final ThemeData base = ThemeData.light();
return base.copyWith(
colorScheme: base.colorScheme.copyWith(
primary: kShrinePurple,
secondary: kShrinePurple,
error: kShrineErrorRed,
),
scaffoldBackgroundColor: kShrineSurfaceWhite,
textSelectionTheme: const TextSelectionThemeData(
selectionColor: kShrinePurple,
),
appBarTheme: const AppBarTheme(
foregroundColor: kShrineBrown900,
backgroundColor: kShrinePink100,
),
inputDecorationTheme: const InputDecorationTheme(
border: CutCornersBorder(),
focusedBorder: CutCornersBorder(
borderSide: BorderSide(
width: 2.0,
color: kShrinePurple,
),
),
floatingLabelStyle: TextStyle(
color: kShrinePurple,
),
),
);
}
راهاندازی مجدد فوری. اکنون تم جدید باید ظاهر شود.
اندروید | آیاواس |
|
|
اندروید | آیاواس |
|
|
نتیجه بسیار متفاوت است! بیایید _buildShrineTheme app.dart's به حالت قبل از این مرحله برگردانیم. یا کد آغازین 104 را دانلود کنیم.
۱۰. تبریک میگویم!
تا الان، شما اپلیکیشنی ساختهاید که شبیه مشخصات طراحی طراحتان است.
مراحل بعدی
اکنون از Material Flutter زیر استفاده کردهاید: تم، تایپوگرافی، ارتفاع و شکل. میتوانید اجزا و زیرسیستمهای بیشتری را در کتابخانه Material Flutter بررسی کنید.
Dig into the files in the supplemental directory to learn how we made the horizontally scrolling, asymmetric layout grid.
اگر طراحی برنامهی شما شامل عناصری باشد که در کتابخانهی آن کامپوننتی وجود ندارد، چه میشود؟ در MDC-104: Material Advanced Components ما نشان میدهیم که چگونه با استفاده از کتابخانهی Material Flutter کامپوننتهای سفارشی ایجاد کنید تا به ظاهر دلخواه خود برسید.


























