ویجت های دسترس پذیری فلاتر برای افراد کم توان — راهنمای پیشرفته
بسیاری از کاربران موبایل دارای محدودیتهای بینایی، فیزیکی یا ناشی از کهولت سن هستند و این موارد میتوانند مانعی جدی بر سر دیدن و استفاده از صفحههای لمسی باشند. همچنین کاربرانی وجود دارند که قوه شنوایی ضعیفی دارند و بدین ترتیب نمیتوانند صدای نوتیفیکیشنها و هشدارهای صوتی را بشنوند. بر اساس گزارش انجمن جهانی سلامت، بیش از یک میلیارد انسان با نوعی ناتوانی جسمی زندگی میکنند و بین 110 تا 190 میلیون نفر به دلیل چالشهایی که دارند، قادر به انجام وظایف زندگی روزمره خود نیستند. فناوری، به شرط طراحی صحیح میتواند تأثیر مثبت شگرفی روی زندگی چنین افرادی داشته باشد. فناوری میتواند افرادی را که با چنین مشکلاتی مواجه هستند، توانمند کند و آنها را قادر سازد که به بهرهوری و استقلال بیشتری دست پیدا کنند.
همه کاربران موبایل به یک روش با اپلیکیشنهای موبایل تعامل پیدا نمیکنند. از این رو همواره باید توجه داشته باشید که اپلیکیشنهای خود را برای همه افراد به شیوهای مناسب طراحی کنید. پیادهسازی صحیح دسترسپذیری میتواند منجر به بهبود کیفیت اپلیکیشن شما شود و تعداد نصبها را افزایش دهد. همچنین تأثیر زیادی روی میزان وفاداری کاربران به اپلیکیشن شما خواهد داشت.
در این مقاله قصد داریم نگاهی به ویجتهای دسترسپذیری فلاتر و شیوه کارکرد آنها داشته باشیم. فلاتر یک فریمورک برای برنامهنویسی کراس پلتفرم است که از سوی گوگل عرضه شده است. اگر میخواهید آشنایی بیشتری با فلاتر پیدا کنید، پیشنهاد میکنیم به مطلب زیر مراجعه کنید:
چگونه دسترسپذیری یک اپلیکیشن فلاتر را افزایش دهیم؟
فلاتر سه کامپوننت دارد که از دسترسپذیری پشتیبانی میکنند و در ادامه آنها را یک به یک بررسی میکنیم.
فونتهای بزرگ
برخی افراد زمانی که پیر میشوند دیگر نمیتوانند به خوبی ببینند و بسیاری دیگر نیز از بدو تولد با نقص بینایی مواجه هستند. این افراد غالباً مشکلاتی در خواندن متنهایی با اندازه پیشفرض که اغلب ما استفاده میکنیم، دارند. این نقیصه چنان شایع است که شاید یک میلیارد انسان یا بیشتر را درگیر کرده است. از این رو یکی از مهمترین موارد در زمان طراحی اپلیکیشن این است که بررسی کنیم وقتی کاربری میخواهد در بخش گزینههای دسترسپذیری، متن را بزرگ کند، اندازه متن به طرز صحیح افزایش پیدا کند.
در فلاتر محاسبات اندازه متن به صورت خودکار مدیریت میشوند. ویجت Text یک مشخصه به نام textScaleFactor دارد که به بیان ساده در آن اندازه فونت تعیین شده در مقدار textScaleFactor ضرب میشود تا اندازه فونتی که واقعاً روی صفحه و پیکسلهای منطقی رندر خواهد شد به دست آید. بنابراین اگر میخواهید اندازه متن 150% اندازه نرمال باشد، باید مقدار textScaleFactor را برابر با 1.5 تنظیم کنید.
یک نکته که باید همواره در خاطر داشته باشید این است که اگر textScaleFactor را به صورت دستی تنظیم کنید، محاسبات خودکار اندازه متن از تنظیمات دسترسپذیری کاربر نادیده گرفته میشوند. از این رو تنظیمات دسترسپذیری کاربر دیگر کار نخواهد کرد. اگر این وضعیت منجر به مشکل عمدهای برای کاربر شود، ممکن است کاربر تصمیم به لغو کردن نصب برنامه بگیرد.
اگر هیچ مقداری برای این مشخصه تعیین نکنید، مقدار بازگشتی MediaQueryData.textScaleFactor به همراه متغیر context مرتبط و یا در صورت عدم وجود context مقدار بازگشتی برابر با 1.0 خواهد بود که تأثیری روی اندازه متن ندارد.
اما مقیاسپذیر ساختن متن کافی نیست. اگر در زمان ایجاد «طرحبندی» (Layout) شرایط افزایش اندازه متن از سوی کاربران را به درستی پیشبینی نکرده باشید، ممکن است متن برش یابد و در نهایت موجب بروز مشکلات بیشتری برای کاربر شود که شاید در صورت عدم استفاده از دسترسپذیری اصلاً پیش نمیآمدند. به همین دلیل است که همواره باید کاملاً مطمئن شوید که متون مختلف در زمان تغییر تنظیمات دسترسپذیری به درستی نمایش پیدا کنند.
کنتراست کافی
هنگام پیادهسازی یک اینترفیس اپلیکیشن، باید رنگهای پیشزمینه و پسزمینه را با کنتراست رنگ کافی تعیین کنیم. «نسبت کنتراست» محاسبهای است که در زمان مشاهده یک اینترفیس روی دستگاه در شرایط نور شدید به دست میآید. این نسبت از 1 تا 21 متغیر است و افزایش یافتن آن به معنی کنتراست بالاتر است. ابزارهای زیادی مانند این ابزار (+) برای محاسبه نسبت کنتراست دو رنگ مجاور وجود دارند.
دستورهای W3C به صورت زیر هستند:
- دست کم 1:4.5 برای متن کوچک (کمتر از 18 پوینت از فونت معمولی یا 14 پوینت از فونت bold)
- دست کم 1:3.0 برای متنهای بزرگ (18 پوینت و بالاتر برای فونت معمولی و یا بالاتر از 14 پوینت برای فونتهای bold)
ابزارهای قرائت صفحه
ابزارهای قرائت صفحه برای توانمندسازی افراد با نقص بینایی در جهت استفاده از اپلیکیشنهای شما مانند هر نرمافزار دیگری ضروری هستند.
در اندروید، گوگل یک ابزار قرائت صفحه به نام TalkBack تعبیه کرده است. کاربران با استفاده از TalkBack میتوانند با استفاده از ژستها (یا سوایپ کردن) و یا کیبورد اکسترنال ورودی داشته باشند. هر عمل که از سوی کاربر اجرا شود یک خروجی صوتی ارائه میشود که به کاربر امکان میدهد بداند سوایپ وی موفق بوده است. این ابزارها میتوانند متن را برای کاربر بخوانند و کافی است وی تنها یک پاراگراف را لمس کند تا TalkBack شروع به خواندن آن بکند.
TalkBack
TalkBack میتواند به سادگی با استفاده از فشردن همزمان دکمههای صدا روی دستگاه به مدت 3 ثانیه فعال شود. از طریق منوی تنظیمات هم میتوان آن را فعال کرد.
VoiceOver
اپل نیز در iOS، یک نرمافزار قرائت صفحه دارد که VoiceOver نامیده میشود. VoiceOver نیز مانند TalkBack از ورودیهای با استفاده از ژست پشتیبانی میکند. با استفاده از VoiceOver میتوان نتایج اقدامات کاربر را به صورت شنیداری دریافت کرد. VoiceOver میتواند با کلیک کردن سه بار پشت سرهم دکمه home فعال شود، البته قبلاً بایستی VoiceOver را به میانبرهای دسترسپذیری اضافه کرده باشید. همچنین میتوانید با استفاده از منوی تنظیمات آن را فعال کنید.
اکنون که یک نرمافزار قرائت صفحه داریم، میخواهیم بدانیم وقتی روی یک اپلیکیشن فلاتر اجرا میشود چه اتفاقی میافتد. از آنجا که به محض ایجاد یک پروژه جدید در فلاتر یک اپلیکیشن نمونه به دست میآوریم، نیاز نیست که اپلیکیشن خاص خود را بنویسیم تا بتوانیم از امکان قرائت صفحه بهرهمند شویم. نکتهای که باید به خاطر داشته باشید این است که باید این کار را روی یک دستگاه واقعی انجام دهید و در این مورد، شبیهساز کار نمیکند.
روی دستگاه خود ابزار قرائت صفحه را فعال کرده و اپلیکیشن پیشفرض را باز کنید. بدین ترتیب خواهید دید که ابزار قرائت صفحه شروع به خواندن یک متن میکند. در ادامه نگاهی به طرز کار آن خواهیم داشت.
ویجت Semantics
فلاتر چندین ویجت دسترسپذیری در اختیار ما قرار میدهد که امکان ایجاد اپلیکیشنهایی با امکان دسترسی گسترده برای همه افراد را فراهم میسازد. میدهد. نخستین ویجت که بررسی میکنیم Semantics نام دارد. Semantics درخت ویجت را با توصیف فرزندانش، حاشیهنویسی میکند. شما میتوانید از این حاشیهنویسیها برای اعلام انواع چیزهای مختلف به افراد با نقص بینایی استفاده کنید.
برای نمونه میتوانید یک حاشیهنویسی اضافه کنید تا به این افراد اعلام کنید که متن چه هست، آیا یک دکمه انتخاب شده است و حتی میتوانید به کاربر چیزی در مورد کاری که انجام میدهد و همچنین موارد تپ کردن یا تپ ممتد (Long Tap) را با سرنخهای onTap و onLongPress به وی اعلام کنید.
بنابراین زمانی که میخواهید توصیفی در مورد یک ویجت داشته باشید، میتوانید آن را درون یک ویجت Semantics قرار دهید. بدین ترتیب متوجه میشوید که نرمافزار قرائت صفحه چگونه میتواند اپلیکیشن نمونه ما را بخواند.
اگر کد فوق را بررسی کنید، میبینید که در صورت وجود یک عنوان، درون یک ویجت Semantics قرار میگیرد. در ویجتهای فلاتر میبینیم که در اغلب موارد ویجتهای دسترسپذیری از قبل پیادهسازی شدهاند. اما اگر Semantics را از کد منبع پاک کنید و اپلیکیشن را مجدداً اجرا کنید، میبینید که این بار TalkBalk دیگر نمیتواند عنوان را بخواند.
هنگامی که یک درخت ویجت ایجاد میکنید، فلاتر نیز یک درخت Semantics به همراه SemanticNodes ایجاد میکند. هر گره میتواند به ما کمک کند که ویجت متناظرش را به کمک ابزار قرائت صفحه توصیف کنیم. همچنین میتواند اقدامهای سفارشی یا از پیش تعریفشدهای از SemanticsAction داشته باشد.
سازنده ویجت Semantics
تا به این جا Semantics یک ابزار کاملاً جالب به نظر رسیده است، اما چگونه میتوانیم چنین ویجتی بسازیم؟ در ادامه سازنده آن را بررسی میکنیم:
همان طور که میبینید سازنده استاندارد در زمان بسط دادن آن از کلاس پایه SingleChildRenderObjectWidget، برای Semantics مقدار زیادی مشخصههای مختلف ایجاد میکند. در سازنده دیگر Semantics.fromProperties به یک شیء SemanticsProperties به نام properties نیاز دارد. بر اساس مستندات، اگر بخواهید شیء Semantics خود را به صورت ثابت ایجاد کنید، باید به این ترتیب عمل کنید.
مشخصهها در کلاس SemanticsProperties برای تولید یک SemanticsNode در گره استفاده میشوند، اما این مورد را در ادامه بررسی خواهیم کرد. ما میخواهیم در حال حاضر به درک صحیحی از این مشخصهها برسیم، زیرا این موارد هستند که به ما امکان میدهند دسترسپذیری را به طرز مؤثری در اپلیکیشن پیادهسازی کرده و بهترین تجربهها را برای کاربران خود رقم بزنیم.
جدول موجود در این صفحه (+) را ملاحظه کنید. به خاطر داشته باشید که این مشخصهها به صورت پیشفرض null هستند. توضیحات به روشی نوشته شدهاند که انتظار میرود از سوی اغلب افراد درک شوند. همچنان که میبینید جدول فوق روشهای زیادی برای توصیف ویجت مرتبط ارائه میکند. برای نمونه مثالی از SDK فلاتر در مورد روش استفاده تیم فلاتر از SemanticsProperties را بررسی میکنیم.
Semantics برای یک ویجت ListTile به صورت زیر است. ListTile را میتوان به عنوان آیتم آخر نیز در نظر گرفت چون یک آیتم منفرد درون یک لیست است که شباهت زیادی به یک توییت منفرد در صفحه اصلی توییتر دارد.
1 /// List tile widget creation with Semantics
2 return InkWell(
3 onTap: enabled ? onTap : null,
4 onLongPress: enabled ? onLongPress : null,
5 child: Semantics(
6 selected: selected,
7 enabled: enabled,
8 child: SafeArea(
9 top: false,
10 bottom: false,
11 minimum: resolvedContentPadding,
12 child: _ListTile(
13 leading: leadingIcon,
14 title: titleText,
15 subtitle: subtitleText,
16 trailing: trailingIcon,
17 isDense: _isDenseLayout(tileTheme),
18 isThreeLine: isThreeLine,
19 textDirection: textDirection,
20 titleBaselineType: titleStyle.textBaseline,
21 subtitleBaselineType: subtitleStyle?.textBaseline,
22 ),
23 ),
24 ),
25 );
طرز کار عناصر «معنا شناختی» (Semantics)
در ادامه به بررسی این کد و کارکرد آن برای کاربران میپردازم. قبل از چیز میتوانیم ببینیم که به یک شیء مستقل SemanticsProperties نیاز نداریم. با این وجود، میتوانیم چنین شیئی را با استفاده از سازندهای با نام fromProperties در کلاس Semantics بسازیم. ما میتوانیم برخی اطلاعات وضعیت ویجت را در زمان ایجاد شدنش ارسال کنیم. ما قادر هستیم ببینیم که فلگهای فعالشده و منتخب با مقادیری که درون سازنده ویجت تعریفشدهاند، تحریک میشوند.
اگر ListTile را هم اینک بسازیم، شروع به خواندن متن درون خود با صدای بلند میکند و همچنین اعلام میکند که متن فعال/غیرفعال و یا انتخاب شده یا نشده است. امکان تعیین دینامیک مقادیر برای ListTile جهت ایجاد اطلاعات معناشناختی سفارشی برای هر کادر منفرد وجود دارد:
1 ListView.builder(
2 itemCount: 5,
3 itemBuilder: (context, position) {
4 return ListTile(
5 enabled: position == 1 ? true : false,
6 selected: position == 0 ? true : false,
7 title: Text('Main title for $position item'),
8 subtitle: Text('Sub title for $position item'),
9 );
10 },
11 ),
تست عناصر معناشناختی
قطعه کد فوق یک «نمای لیست» (List View) با 5 عنصر میسازد و همه آنها را به جز عنصر دوم غیرفعال میکند. همچنین حالت منتخب عنصر نخست را به صورت true تعیین میکند. هنگامی که اپلیکیشن را با فعالسازی ابزار قرائت صفحه اجرا کنیم پیام زیر خوانده میشود:
Selected main title for 0 item, sub title for 0 item disabled
همان طور که میبینید، این پیام اطلاعاتی که در مورد هر آیتم ارائه کردیم را به کاربر انتقال میدهد. با این حال باید حالتهای دیگر را نیز تست کنیم تا از کارکرد صحیح آن مطمئن شویم. اگر یک بار روی آیتم دوم کلیک کنیم، عبارت زیر را میشنویم:
Main title for 1 item, sub title for 1 item
از آنجا که عنصر دوم انتخاب و فعال نشده است؛ میتوانیم مطمئن باشیم که آن نیز به صورت صحیحی کار میکند. با استفاده از TalkBalk، یک کلیک موجب میشود که ابزار قرائت صفحه به کار بیفتد؛ اما برای فعال کردن onTap در عمل به دو بار تپ کردن نیاز هست. برای تست آخرین حالت، روی سومین عنصر ضربه میزنیم. این بار پیام زیر را میشنویم:
Main title for 2 item, sub item for 2 item disabled
از آنجا که ما آن را انتخاب نکردهایم و غیر فعال است، به درستی اجرا شده است و میتوانیم مطمئن باشیم که به طرز صحیحی کار میکند. اکنون که درکی ابتدایی از ابزار Semantics و روش ساخت عناصر معناشناختی یافتیم، به بررسی عمیقتر این مفاهیم میپردازیم. اما قبل از آن باید در مورد مفهومی که قبلاً اشاره کردیم یعنی SemanticsNode بیشتر بدانیم.
درخت Semantics
همان طور که پیشتر اشاره شد، هنگامی که درخت ویجت ایجاد میشود یک درخت Semantics نیز همراه با آن ساخته میشود و این درخت است که مورد استفاده ابزارهای قرائت صفحه قرار میگیرد. در دنیای برنامهنویسی، منظور از «درخت» (tree) یک ساختمان داده شامل «گره» (node) و «برگ» (leaf) است.
در حالت مورد بررسی، SemanticsNodes گرههای ما هستند. هر SemanticsNode یک گره است که دادههای معناشناختی را به نمایش میگذارد. هر گره میتواند دادههای معناشناختی را برای یک یا چند ویجت پوشش دهد. هر SemanticsNode مقادیری دارد که میتواند از سوی اَعمال معناشناختی یا SemanticsAction فعال شوند. برای نمونه SemanticsProperties دارای پارامترهایی با عناوین increasedValue و decreasedValue برای اَعمال increase و decrease است. همچنین دارای یک «کلید» (key) برای شناسایی فهرست گرهها هستند.
این موارد در طی تجزیه درخت برای شناسایی گره صحیح در زمان بازسازی به کار میآیند. همچنین یک مقدار id برای شناسایی وجود دارد. برای نمونه مقدار id برای گره ریشه برابر با 0 است. این مقدار برای در زمان ایجاد گرههای فرزند به صورت خودکار تولید میشود.
علاوه بر آن میتوانیم اطلاعاتی در مورد گره و رابطه آن با گرههای دیگر بیابیم. از این رو میتوانیم در هر لحظه با استفاده از فلگ isPartOfNodeMerging بررسی کنیم که آیا با گرههای دیگر ادغام شده است یا نه. همچنین با استفاده از isMergedIntoParent میتوانیم بررسی کنیم که آیا قبلاً ادغام شده است یا نه. اگر یک ویجت چند فرزند داشته باشد که گردش خاص خود را دارند، میتوانیم از mergeAllDescendantsIntoThisNode برای ادغام همه آن گرهها در یک گره منفرد استفاده کنیم.
Semantics سفارشی
اکنون که درک بهتری از SemanticsNode ،SemanticsProperties و Semantics داریم، میتوانیم Semantics سفارشی خاص خود را بسازیم.
1 ListView.builder(
2 itemCount: 5,
3 itemBuilder: (context, position) {
4 return Semantics(
5 label: 'Container with 200 width 200 height and red background',
6 enabled: position == 1 ? true : false,
7 selected: position == 0 ? true : false,
8 onTap: () {
9 Scaffold.of(context).showSnackBar(SnackBar(content: Text('Item $position Clicked!')));
10 },
11 onScrollDown: (){
12 print('Scroll down happened');
13 },
14 child: Container(
15 margin: EdgeInsets.all(16),
16 color: Colors.red,
17 height: 200,
18 width: 200,
19 ),
20 );
21 },
22 )
در کد فوق، ما از برچسب معناشناختی برای توصیف هر کانتینر استفاده میکنیم که در ListView مورد استفاده قرار میگیرد. هر کدام از این موارد یک کادر قرمزرنگ با ارتفاع و عرض 200 هستند. ما مقادیر enable و selected را از مثال فوق نگه داشتهایم. با این وجود، کنترلهای دیگری را نیز اضافه خواهیم کرد. یک callback برای onTop ایجاد میکنیم که برای دابل کلیک استفاده میشود و از onScrollDown نیز برای تست ژستها استفاده میکنیم. به طور کلی اپلیکیشن ما یک Snackbar نمایش میدهد که عبارت زیر را بیان خواهد کرد:
Item <related position> Clicked!
اگر onTop تحریک شود و یا زمانی که اسکرول میکنید (این کار در اندروید از طریق سوایپ کردن به چپ و سپس به سمت پایین انجام مییابد)، یک مدخل لاگ ایجاد میشود که نشان میدهد callback تحریک شده است.
مشاهده طرز کار همه این موارد تا به این جا جالب بوده است، اما زمانی که دقیقتر میشویم، سؤالات بیشتر و بیشتری برای ما ایجاد میشوند. زمانی که بخواهیم چند عنصر معناشناختی را در یک عنصر ادغام کنیم چه اتفاقی میافتد؟ یا اگر نخواهیم اطلاعات معناشناختی خاصی را به کاربر ارائه نکنیم چه رخ خواهد داد؟
ادغام عناصر معناشناختی
لازم نیست در مورد این مسائل نگران باشید، فلاتر همه این موارد را پوشش میدهد. امکان ادغام عناصر معناشناختی ویجتها با استفاده از MergeSemantics وجود دارد، حتی میتوانید برخی از آنها را با استفاده از ExcludeSemantics حذف کنید. علاوه بر اینها، فلاتر ویجتهای دیگری مانند BlockSemantics و IndexedSemantics نیز برای کارکردهای معناشناختی دارد که در ادامه به بررسی آنها میپردازیم.
به این منظور مثال قبلی را با استفاده از کد زیر بسط میدهیم:
1 ListView.builder(
2 itemCount: 5,
3 addSemanticIndexes: false,
4 semanticChildCount: 3,
5 itemBuilder: (context, position) {
6 return MergeSemantics(
7 child: Semantics(
8 label: 'Container with 200 width 200 height and red background',
9 enabled: position == 1 ? true : false,
10 selected: position == 0 ? true : false,
11 onTap: () {
12 Scaffold.of(context).showSnackBar(
13 SnackBar(content: Text('Item $position Clicked!')));
14 },
15 onScrollDown: () {
16 print('Scroll down happened');
17 },
18 child: Container(
19 margin: EdgeInsets.all(16),
20 color: Colors.red,
21 height: 200,
22 width: 200,
23 child: Column(
24 children: <Widget>[
25 Text('First inside text of item $position'),
26 BlockSemantics(
27 child: Text('Second inside text of item $position')),
28 ExcludeSemantics(
29 child: Text('Third inside text of item $position')),
30 Text('Fourth inside text of item $position')
31 ],
32 ),
33 ),
34 ),
35 );
همان طور که میبینید ما کد را کمی تغییر دادهایم. MergeSemantics را به عنوان root اضافه کردهایم. این بدان معنی است که همه عناصر معناشناختی فرزند موجود با هم ادغام میشوند و ابزار قرائت صفحه، همه آنها را یک جا ادغام میکند.
ضمناً یک ستون برای فرزندان درون کانتینر خود قرار میدهیم. در فرزند دوم در آیتم لیست، یعنی کانتینر دوم، میتوان دید که از BlockSemantics استفاده شده است. از این رو ویجتهای قبل از این گره نادیده گرفته میشوند و از سوی ابزارهای قرائت صفحه خوانده نمیشوند.
در فرزند سوم در آیتم لیست نیز یک ExcludeSemantics وجود دارد. بدین ترتیب ویجت فرزند این ویجت معناشناختی بخشی از درخت معناشناختی نخواهد بود. اپلیکیشن را بار دیگر اجرا میکنیم و عنصر نخست را بررسی میکنیم. در این زمان ابزار قرائت صفحه باید عبارت زیر را بخواند:
Selected Container with 200 width 200 height and red background second inside text of item 0 fourth inside text of item 0 disabled.
اندیسگذاری عناصر معناشناختی
همان طور که شاهد هستید، همه عناصر معناشناختی به جز آن که نمیخواهیم به اشتراک بگذاریم، در یک عنصر گرداوری شدهاند. ما هنوز یکی از عناصر معناشناختی که قبلاً اشاره کردیم، یعنی IndexedSemantics را بررسی نکردهایم. IndexedSemantics به ما کمک میکند که رد اطلاعات مرتبط را که به دسترسپذیری ابزارهای قرائت صفحه کمک میکنند حفظ کنیم. برای نمونه، با استفاده از ListView یک IndexedSemantics برای هر عنصر منفرد ایجاد خواهد شد.
اما در ListView ممکن است برخی عناصر باشند که کاربردی ندارند یعنی ممکن است عناصر جداسازی لیست باشند که هیچ کارکردی به جز بازنمایی دیداری ندارند. برای این که از قرائت این موارد برای کاربر جلوگیری کنیم، میتوانیم از IndexedSemantics به صورت زیر استفاده کنیم:
1ListView(
2 addSemanticIndexes: false,
3 semanticChildCount: 2,
4 children: const <Widget>[
5 IndexedSemantics(index: 0, child: Text('First')),
6 Spacer(),
7 IndexedSemantics(index: 1, child: Text('Second')),
8 Spacer(),
9 ],
10)
در این مثال، ابزارهای دسترسپذیری در زمان قرائت صفحه تنها عناصری را در نظر میگیرند که IndexedSemantics دارند و از روی باقی موارد رد میشوند.
سخن پایانی
دسترسپذیری موضوع مهمی است و هرگز نباید آن را نادیده گرفت. در زمان طراحی اپلیکیشن، همواره باید دسترسپذیری را در نظر داشت و اطمینان یافت که جنبههای دسترسپذیری به اپلیکیشن اضافه شدهاند و در دسترس همه افرادی که از گوشیهای هوشمند استفاده میکنند، قرار دارند. بدین ترتیب با اندکی تلاش بیشتر باعث میشویم، زندگی افراد بسیار زیادی آسانتر شود.
از آنجا که تیم فلاتر قبلاً عناصر معناشناختی را در اغلب ویجتها پیادهسازی کردهاند، اجرای آن برای ما آسانتر شده است. اما زمانی که یک ویجت سفارشی ایجاد میکنیم باید همواره عناصر معناشناختی را نیز به آن اضافه کنیم. به خاطر داشته باشید که هر فردی شایسته این است که بتواند از اپلیکیشن شما استفاده کند، بنابراین کمک کنید که بتوانند از اپلیکیشنتان استفاده کنند.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی اندروید
- مفاهیم مقدماتی فلاتر (Flutter) — به زبان ساده
- مجموعه آموزشهای برنامهنویسی
- گوگل فلاتر (Flutter) از صفر تا صد — ساخت اپلیکیشن به کمک ویجت
- آموزش گوگل فلاتر (Flutter ): ساخت اپلیکیشن دستورهای آشپزی
==
خیلی مقاله هاتون خوبه واقعا بدردم خورد