جیٹ پیک کمپوز کے ساتھ قابل رسائی اینڈرائیڈ ایپس کیسے بنائیں: ایک جامع گائیڈ

آپ کی موبائل ایپ کو قابل رسائی بنانا یقینی بناتا ہے کہ ہر کوئی، بشمول بصری، سماعت، موٹر، ​​یا علمی معذوری والے افراد، ایپ کے ساتھ بات چیت اور مؤثر طریقے سے نیویگیٹ کر سکتے ہیں۔

تاریخی طور پر، رسائی کو اکثر بعد میں سوچا جاتا رہا ہے۔ یہ صرف غور کرنے کی چیز ہے اگر لانچ سے پہلے وقت اجازت دیتا ہے۔

آج، یہ نقطہ نظر بنیادی طور پر بدل گیا ہے. جیسا کہ یورپی ایکسیسبیلٹی ایکٹ (EAA) جیسے ضوابط پورے یورپی یونین کی مارکیٹ میں لاگو ہوتے ہیں، قابل رسائی سافٹ ویئر بنانا ایک تیزی سے قانونی اور کاروباری ضرورت بن گیا ہے۔

مزید اہم بات یہ ہے کہ قابل رسائی ایپلی کیشنز کی تعمیر صرف اچھی انجینئرنگ ہے۔ ایکسیسبیلٹی ایپس تمام صارفین کے لیے استعمال کو بہتر بنانے میں مدد کرتی ہیں اور اس بات کو یقینی بناتی ہیں کہ آپ اپنے سامعین کے ایک اہم حصے کو خارج نہ کریں۔

Jetpack Compose موجودہ Android View سسٹم کے مقابلے رسائی کو آسان بناتا ہے۔ تحریر اعلانیہ اور ریاستی ہے، لہذا یہ بصری صارف انٹرفیس کے ساتھ سیمنٹک میٹا ڈیٹا کا انتظام کرتا ہے۔

اس جامع گائیڈ میں، آپ یہ سیکھیں گے کہ جیٹ پیک کمپوز میں ایکسیسبیلٹی کیسے کام کرتی ہے، سیمنٹک ٹریز کا استعمال کیسے کیا جاتا ہے، ضروری اور جدید ایکسیسبیلٹی پیٹرن کو کیسے لاگو کیا جاتا ہے، اور خودکار ٹیسٹنگ، Google کے ایکسیسبیلٹی اسکینر، اور Android اسٹوڈیو کے لے آؤٹ انسپکٹر اور ٹاک بیک کا استعمال کرتے ہوئے اپنی ایپ کی مکمل جانچ کیسے کی جاتی ہے۔

شرطیں

اس گائیڈ پر عمل کرنے کے لیے آپ کو ضرورت ہو گی:

  • کوٹلن اور جیٹ پیک کمپوز کا بنیادی علم (مثلاً کمپوز ایبلز، موڈیفائر، اسٹیٹ)

  • اینڈرائیڈ اسٹوڈیو (ہیج ہاگ، آئیگوانا، جیلی فش، کوآلا، لیڈی بگ اور بعد میں)۔

  • ایک اینڈرائیڈ ڈیوائس یا ایمولیٹر جس میں گوگل پلے اسٹور تک رسائی ہو اور اینڈرائیڈ 9.0 (API 28) یا اس سے اوپر والا (Google Accessibility Scanner کا تازہ ترین ورژن انسٹال اور چلانے کے لیے)۔

انڈیکس

جدید اینڈرائیڈ ڈیولپمنٹ میں رسائی کیوں اہم ہے۔

ورلڈ ہیلتھ آرگنائزیشن (ڈبلیو ایچ او) کے مطابق، 1.3 بلین سے زیادہ لوگ (دنیا کی آبادی کا تقریباً 16 فیصد) شدید معذوری کے ساتھ زندگی گزار رہے ہیں۔ اس میں مستقل بصارت کی خرابی، سماعت سے محرومی، جسمانی حرکات کی پابندیاں، علمی یا اعصابی اختلافات والے لوگ شامل ہیں۔

مستقل معذوری کے علاوہ، صارفین کو عارضی یا حالات کی حدود کا سامنا کرنا پڑ سکتا ہے۔ جو لوگ اپنے بچوں کو ایک ہاتھ سے پکڑتے ہیں ان میں موٹر کی عارضی خرابی ہوتی ہے۔ جو لوگ دوپہر کی سخت سورج کی روشنی میں سیل فون استعمال کرتے ہیں وہ حالات کے لحاظ سے بصری خرابی کا تجربہ کرتے ہیں۔ اور شور مچانے والے ہوائی اڈے کے ٹرمینل میں کسی کو حالات کی سماعت کی حدود کا سامنا کرنا پڑتا ہے۔

آپ کی ایپ کو قابل رسائی بنانے کے لیے ڈیزائن کرنا اس بات کو یقینی بناتا ہے کہ آپ کا انٹرفیس ان تمام منظرناموں وغیرہ میں لچکدار اور قابل استعمال رہے۔

ہمدردی اور جامع ڈیزائن کے علاوہ، رسائی تیزی سے بین الاقوامی قانون کے تابع ہے۔

یورپی یونین میں یورپی رسائی ایکٹ (EAA) اسے مصنوعات اور خدمات کی ایک متعین فہرست تک رسائی کی ضرورت ہوتی ہے، بشمول اسمارٹ فونز اور کمپیوٹرز، ای کامرس، صارفین کی مالیاتی خدمات، ای کتابیں، اور مسافروں کی نقل و حمل کی خدمات۔ عملی طور پر، تعمیل عام طور پر اس کے لیے ظاہر کی جاتی ہے: EN 301 549ڈیجیٹل مصنوعات اور خدمات کے لیے یورپی رسائی کا معیار۔

امریکہ میں امریکی معذوری ایکٹ (ADA) یہ ریاستی اور مقامی حکومتوں پر لاگو ہوتا ہے (عنوان II، جس میں واضح ویب اور موبائل ایپ کے قوانین ہیں جن کے لیے WCAG 2.1 لیول AA کی تعمیل 2024 سے شروع ہو رہی ہے) اور عوامی رہائش (ٹائٹل III) پر ہوتا ہے۔ الگ الگ، آرٹیکل 508 بحالی ایکٹ وفاقی ایجنسیوں کو معلومات اور مواصلاتی ٹیکنالوجی تک رسائی فراہم کرنے کا تقاضا کرتا ہے۔

ان معیارات کو پورا کرنے میں ناکامی کے نتیجے میں قانونی جرمانے اور آپ کے برانڈ امیج کو نقصان پہنچ سکتا ہے۔ اس کے برعکس، رسائی کو ترجیح دینا آپ کی مجموعی مارکیٹ کو وسعت دیتا ہے اور صارف کی برقراری کو بڑھاتا ہے۔

معیار بھی تقسیم کو متاثر کرتا ہے۔ گوگل کی اینڈرائیڈ وائٹلز دستاویز میں کہا گیا ہے کہ صارف کے خیال میں کریش کی اعلی شرح گوگل پلے پر ایپ کی دریافت کو کم کرتی ہے۔

اینڈرائیڈ کی رسائی کے بنیادی تصورات

Jetpack Compose میں قابل رسائی ایپلی کیشنز کو ڈیزائن کرنے کے لیے، آپ کو یہ سمجھنے کی ضرورت ہے کہ مقامی Android آپریٹنگ سسٹم کس طرح معاون ٹیکنالوجیز کے ساتھ بات چیت کرتا ہے۔

Android ایکسیسبیلٹی سروسز کو سمجھنا

Android میں کئی بلٹ ان ایکسیسبیلٹی سروسز شامل ہیں جو بیک گراؤنڈ پروسیس کے طور پر چلتی ہیں۔ یہ سروسز ایپ کے یوزر انٹرفیس کو ہائی جیک کرتی ہیں اور اسے متبادل حسی فیڈ بیک یا متبادل ان پٹ میکانزم میں تبدیل کرتی ہیں۔

  • ٹاک بیک (اسکرین ریڈر): TalkBack ایک اسکرین ریڈر ہے جسے Android میں بنایا گیا ہے جو نابینا اور کم بصارت والے صارفین کے لیے ڈیزائن کیا گیا ہے۔ انٹرفیس عناصر کا معائنہ کریں، بصری مواد اور معنوی وضاحتوں کو ترکیب شدہ اسپیچ اور ہیپٹک وائبریشنز میں تبدیل کریں، اور لکیری سوائپ اشاروں کا استعمال کرتے ہوئے غیر بصری نیویگیشن کو فعال کریں۔

  • سوئچ رسائی: موٹر کی شدید معذوری والے صارفین کے لیے ڈیزائن کیا گیا ہے جو فزیکل ٹچ اسکرین استعمال نہیں کر سکتے ہیں، سوئچ رسائی صارفین کو ایک یا زیادہ فزیکل سوئچز (مثلاً، فٹ ​​پیڈل، سیپ ڈیوائس، یا سنگل بٹن) یا منسلک کی بورڈ کا استعمال کرتے ہوئے ڈیوائس کو کنٹرول کرنے کی اجازت دیتی ہے۔ یہ ترتیب وار توجہ کے قابل اسکرین عناصر کو اسکین کرتا ہے اور صارف کو نمایاں کردہ آئٹم کو منتخب کرنے کی اجازت دیتا ہے۔

  • آواز تک رسائی: صارفین کو صوتی کمانڈز کا استعمال کرتے ہوئے اپنے پورے فون کو کنٹرول کرنے کی اجازت دیتا ہے (جیسے "پریس اوپن”، "اسکرول ڈاؤن” یا "ہیلو ٹائپ کریں”)۔ ان کے قابل رسائی لیبلز کی بنیاد پر متعامل عناصر کو عددی بیجز تفویض کریں، تاکہ صارف نمبروں کے ساتھ کارروائیاں انجام دے سکیں۔

  • بولنے کا انتخاب کریں: صارفین مکمل ٹاک بیک نیویگیشن آن کیے بغیر، مخصوص پیراگراف، بٹن یا آئیکنز کو بولے ہوئے سننے کے لیے اسکرین پر نمایاں کر سکتے ہیں۔

یہ سبھی قابل رسائی خدمات ایک مشترکہ ضرورت کا اشتراک کرتی ہیں: یعنی، یہ بصری پکسلز کے ساتھ براہ راست تعامل نہیں کرتی ہے۔ اس کے بجائے وہ کچھ اس طرح پڑھتے ہیں: معنوی درخت آپ کی درخواست سے تیار کردہ۔

کمپوز سیمنٹک ٹری کیسے کام کرتا ہے۔

جب آپ جیٹ پیک کمپوز میں صارف انٹرفیس بناتے ہیں تو کمپوز دو الگ لیکن جڑے ہوئے اندرونی درختوں کے ڈھانچے بناتا ہے۔

  1. لے آؤٹ (UI) درخت: اس درخت میں بصری رینڈرنگ نوڈس (جیسے کینوس، باکس، قطار، کالم، متن، اور تصویر) شامل ہیں جو اسکرین پر پکسلز کی پیمائش، جگہ اور ڈرائنگ کرتے ہیں۔

  2. معنوی درخت: یہ درخت ترتیب کے درخت کے متوازی چلتا ہے۔ یہ میٹا ڈیٹا پر مشتمل ہے جو ہر عنصر کے معنی، مقصد، حالت اور انٹرایکٹو فعالیت کو بیان کرتا ہے۔

فرش بصری لے آؤٹ ٹری (UI اور پکسل) سیمنٹک ٹری (قابل رسائی اور ٹاک بیک)
کنٹینر Row(modifier = Modifier.clickable { ... }) سنگل ضم شدہ ایکسیسبیلٹی نوڈ
بچہ 1 Image(Icons.Default.Star) والدین کی تفصیل میں ضم ہو گیا۔
بچے 2 Text("4.5") والدین کی تفصیل میں ضم ہو گیا۔
بچے 3 Text("Rating") والدین کی تفصیل میں ضم ہو گیا۔
نتیجہ اسکرین پر الگ الگ بصری پکسلز پیش کریں۔ TalkBack درج ذیل کا اعلان کرتا ہے: "درجہ بندی: 4.5 ستارے، بٹن”

معیاری مواد کمپوز اجزاء، جیسے Button, Checkbox, Slider, Switchاور Text) خود بخود سیمنٹک درخت کو مناسب سیمنٹک خصوصیات کے ساتھ آباد کرتا ہے۔ مثال کے طور پر، Button کمپوز ایبل خود بخود اس کردار کو سیٹ کرتا ہے: Role.Button ایک کلک ایکشن منسلک کریں۔

تاہم، اگر آپ اپنی مرضی کے مطابق لے آؤٹ، کینوس کی تصاویر، یا غیر معیاری انٹرایکٹو ویجیٹس بناتے ہیں، تو تحریر خود بخود آپ کے ڈیزائن کے ارادے کا اندازہ نہیں لگا سکتا۔ ان صورتوں میں، آپ کو کمپوز کے سیمنٹک موڈیفائر کا استعمال کرتے ہوئے سیمنٹک ٹری کو دستی طور پر بڑھانا ہوگا۔

WCAG 2.1 POUR اصول

ڈیجیٹل رسائی کے لیے بین الاقوامی معیارات ویب مواد تک رسائی کے رہنما خطوط (WCAG) 2.1ورلڈ وائڈ ویب کنسورشیم (W3C) کے ذریعہ شائع کردہ۔ ہدایات چار بنیادی اصولوں کے ارد گرد ترتیب دی گئی ہیں، جنہیں ان کے مخففات سے جانا جاتا ہے: ڈالو:

  • قابل شناخت: معلومات اور UI اجزاء کو اس طریقے سے پیش کیا جانا چاہیے جس سے صارفین سمجھ سکیں۔ مواد صارف کے تمام حواس کے لیے پوشیدہ نہیں ہو سکتا۔ اینڈرائیڈ ایپس میں، اس کا مطلب ہے تمام بصری میڈیا کے لیے وضاحتی متن کے متبادل فراہم کرنا، ڈائنامک فونٹ اسکیلنگ کو سپورٹ کرنا، اور اعلی رنگ کے تضاد کو برقرار رکھنا۔

  • قابل عمل: یوزر انٹرفیس کے اجزاء اور نیویگیشن قابل عمل ہونا چاہیے۔ صارفین کو تمام تعاملات انجام دینے کے قابل ہونا چاہیے چاہے وہ ٹچ اسکرین، ہارڈویئر کی بورڈ، وائس کمانڈ، یا سوئچ ڈیوائس استعمال کریں۔ اس کے لیے ایک مناسب ٹچ ٹارگٹ (Android کے رہنما خطوط کم از کم 48dp × 48dp ہیں) اور ایک منطقی نیویگیشن آرڈر کی ضرورت ہے۔

  • قابل فہم: صارفین کو معلومات اور انٹرفیس کے آپریشن دونوں کو سمجھنے کے قابل ہونا چاہیے۔ اس کا مطلب ہے واضح لیبل لکھنا، بامعنی توثیق کے خرابی کے پیغامات فراہم کرنا، ترتیب میں اچانک اور غیر متوقع تبدیلیوں سے گریز کرنا، اور اپنی شکلوں کو پیشین گوئی کے مطابق ترتیب دینا۔

  • مضبوط: مواد کو اتنا مضبوط ہونا چاہیے کہ متعدد صارف ایجنٹوں اور معاون ٹیکنالوجیز کے ذریعے قابل اعتماد طریقے سے تشریح کی جا سکے۔ کمپوز میں، اس کا مطلب ہے ہیکی ورک آراؤنڈز سے گریز کرنا، معیاری سیمنٹک رولز کا استعمال کرنا، اور سسٹم لیول صارف کی ترجیحات کا احترام کرنا۔

جیٹ پیک کمپوز کے سیمنٹکس

اس سیکشن میں، ہم دیکھیں گے کہ کمپوز کس طرح سیمنٹک میٹا ڈیٹا کو بے نقاب اور ہیرا پھیری کرتا ہے۔

سیمنٹکس کیا ہے؟

جیٹ پیک کمپوز کی سیمنٹکس کلیدی قدر کی خصوصیات ہیں جو لے آؤٹ نوڈس کے ساتھ منسلک ہیں: Modifier.semantics ترمیم کرنے والا۔ یہ مندرجہ ذیل معلومات فراہم کرتا ہے:

  • عنصر کا نام (contentDescription)

  • یہ کس قسم کے UI کنٹرول کی نمائندگی کرتا ہے (role = Role.Checkbox, Role.Button, Role.Tab)

  • موجودہ صورتحال کیا ہے (stateDescription = "Checked", progressBarRangeInfo)

  • صارفین کیا کر سکتے ہیں (onClick, onLongClick, customActions)

بنیادی معنوی خصوصیات اور مواد کی تفصیل

سب سے زیادہ استعمال ہونے والی معنوی خصوصیات ہیں: contentDescription. غیر متنی UI عناصر جیسے شبیہیں، تصاویر، اور ویکٹر گرافکس کی مقامی متنی نمائندگی فراہم کرتا ہے۔

بصری جزو کے لیے مواد کی تفصیل فراہم کرنے کا طریقہ یہاں ہے:

// A functional icon button that performs an action
IconButton(onClick = { /* Open camera */ }) {
    Icon(
        painter = painterResource(id = R.drawable.ic_camera),
        contentDescription = "Open camera"
    )
}

// A decorative background illustration
Image(
    painter = painterResource(id = R.drawable.decorative_pattern),
    contentDescription = null, // Informs TalkBack to skip this node completely
    modifier = Modifier.fillMaxWidth()
)

یہ اندرونی طور پر کیسے کام کرتا ہے۔

ٹاک بیک Iconیہ پڑھتا ہے: contentDescription اسے اونچی آواز میں کہیں (جیسے "کیمرہ کھولیں، بٹن، چالو کرنے کے لیے دو بار تھپتھپائیں”)۔ TalkBack خود بخود لفظ ‘بٹن’ شامل کرتا ہے۔ IconButton بے نقاب Role.Button. (صحیح TalkBack کے جملے ورژن اور علاقے کے لحاظ سے مختلف ہوتے ہیں۔ اس گائیڈ میں صوتی مثالیں صرف مثال کے مقاصد کے لیے ہیں۔)

آرائشی عناصر کے لیے (جیسے پس منظر کی لطیف شکلیں، تقسیم کرنے والے، یا ملحقہ وضاحتی متن کے ساتھ بصری تصویریں)، آپ کو انہیں واضح طور پر سیٹ کرنا چاہیے۔ contentDescription = null. ماحول contentDescription = null تحریر کو ان عناصر کو سیمنٹک ٹری سے خارج کرنے کی ہدایت کرتا ہے، جس سے اسکرین ریڈرز کو بے معنی بصری شور سے الجھنے سے روکتا ہے۔

حسب ضرورت سیمنٹکس اور ریاست کی تفصیل

جب کسی عنصر کی حالت متحرک طور پر تبدیل ہوتی ہے (مثال کے طور پر، پلے اور توقف کے درمیان سوئچ کرنا، یا پھیلنا اور گرنا)، اسکرین ریڈر کے صارفین کو عنصر کے ساتھ تعامل کرنے سے پہلے موجودہ حالت سے آگاہ کرنا ضروری ہے۔

مقرر کیا جا سکتا ہے stateDescription اور role میں Modifier.semantics بلاک:

var isPlaying by remember { mutableStateOf(false) }

IconButton(
    onClick = { isPlaying = !isPlaying },
    modifier = Modifier.semantics {
        // Explicitly declare what state the media player is in
        stateDescription = if (isPlaying) "Playing audio" else "Audio paused"
        role = Role.Button
    }
) {
    Icon(
        imageVector = if (isPlaying) Icons.Default.Pause else Icons.Default.PlayArrow,
        contentDescription = if (isPlaying) "Pause" else "Play"
    )
}

یہ اندرونی طور پر کیسے کام کرتا ہے۔

بغیر stateDescriptionTalkBack صرف کارروائیوں کو پڑھتا ہے ("پلے، بٹن”)۔ صارف کو اندازہ لگانا چاہیے کہ آیا فی الحال آڈیو چل رہا ہے یا بند ہے۔

شامل کرکے stateDescriptionTalkBack اعلان کرتا ہے: "آڈیو چل رہا ہے، توقف، بٹن، سوئچ کرنے کے لیے دو بار تھپتھپائیں۔” یہ صارف کو فوری طور پر موجودہ حالت کو دیکھنے اور کنٹرول کے فعال ہونے پر کارروائی کرنے کی اجازت دیتا ہے۔

mergeDescendants کا استعمال کرتے ہوئے سیمنٹکس کو کیسے ضم کیا جائے۔

پیچیدہ ترتیب میں، بہت سے انفرادی کمپوز ایبلز کو اکثر ایک منطقی شے کی نمائندگی کرنے کے لیے جوڑ دیا جاتا ہے۔ مثال کے طور پر، صارف کی پروفائل قطار میں اوتار کی تصویر، صارف نام، آن لائن بیج، اور ٹائم اسٹیمپ شامل ہو سکتا ہے۔

بطور ڈیفالٹ، TalkBack تمام بچوں کا احاطہ کرتا ہے۔ Text اور Image نوڈس کو آزاد اسٹاپ کے طور پر استعمال کرنے کے لیے صارف کو ایک فہرست آئٹم سے گزرنے کے لیے چار یا پانچ بار سوائپ کرنے کی ضرورت ہوتی ہے۔

آپ استعمال کر سکتے ہیں Modifier.semantics(mergeDescendants = true) تمام چائلڈ نوڈس کو ایک مربوط رسائی نوڈ میں یکجا کرنے کے لیے:

// Bad: TalkBack focuses three separate times: "Star icon", "4.5", "Customer rating"
Row(modifier = Modifier.clickable { /* Navigate to reviews */ }) {
    Icon(
        imageVector = Icons.Default.Star,
        contentDescription = "Star icon"
    )
    Text(text = "4.5")
    Text(text = "Customer rating")
}

// Good: Merged into one single stop: "Customer rating: 4.5 out of 5 stars, button"
Row(
    modifier = Modifier
        .clickable(onClickLabel = "View all reviews") { /* Navigate to reviews */ }
        .semantics(mergeDescendants = true) {
            contentDescription = "Customer rating: 4.5 out of 5 stars"
        }
) {
    Icon(
        imageVector = Icons.Default.Star,
        contentDescription = null // Suppressed because parent provides full description
    )
    Text(text = "4.5")
    Text(text = "Customer rating")
}

یہ اندرونی طور پر کیسے کام کرتا ہے۔

جب mergeDescendants = true سیٹ ہونے پر، کمپوز تمام چائلڈ کمپوز ایبلز کی رسائی کی حدود کو ختم کر دے گا۔ سیمنٹک ٹری میں ایک سے زیادہ اسٹاپس بنانے کے بجائے، کمپوز ایک ہی نوڈ کو ایکسیسبیلٹی فریم ورک میں ظاہر کرتا ہے۔ TalkBack پورے مواد پر فوکس کرتا ہے۔ Row اسے سنگل باؤنڈنگ باکس کے طور پر استعمال کریں اور والدین کے باؤنڈنگ باکس کو پڑھیں۔ contentDescription.

ClearAndSetSemantics کا استعمال کرتے ہوئے سیمنٹکس کو کیسے صاف کریں۔

بعض حالات میں، معیاری کمپوز ایبل میں ڈیفالٹ سیمنٹک رویہ ہوسکتا ہے جو مطلوبہ رسائی کے تجربے میں خلل ڈالتا ہے۔

کہ Modifier.clearAndSetSemantics موڈیفائر چائلڈ کمپوز ایبلز یا بنیادی نفاذ سے وراثت میں ملنے والی تمام سیمنٹک خصوصیات کو ہٹا دیتے ہیں، جس سے آپ صاف حسب ضرورت سیمنٹک تعریفیں بیان کر سکتے ہیں۔

// A composite badge displaying notification count
Box(
    modifier = Modifier.clearAndSetSemantics {
        contentDescription = "3 unread messages"
        role = Role.Button
    }
) {
    Icon(
        imageVector = Icons.Default.Email,
        contentDescription = "Email icon" // Cleared and ignored
    )
    Text(text = "3") // Cleared and ignored
}

یہ اندرونی طور پر کیسے کام کرتا ہے۔

غیر مساوی Modifier.semanticsکوئی بھی شامل کریں یا دوبارہ وضاحت مخصوص کلید، clearAndSetSemantics قابل ترتیب ذیلی درخت میں بنائی گئی تمام موجودہ کلیدوں کو حذف کرتا ہے۔ اوپر کی مثال میں، الگ الگ "ای میل آئیکن” اور "3” ٹیکسٹ نوڈس مکمل طور پر سیمنٹک ٹری سے مٹا دیے گئے ہیں اور ان کی جگہ ایک ہی اطلاع دے دی گئی ہے۔ "3 بغیر پڑھے ہوئے پیغامات، بٹن۔”

ضروری رسائی کے طریقے

اب ہم ان کلیدی قابل رسائی طریقوں کا احاطہ کریں گے جو آپ کو اپنی درخواست میں لاگو کرنے چاہئیں، اس کے ساتھ یہ وضاحت بھی کریں گے کہ ہر مشق کیوں اہم ہے۔

معنی خیز مواد کی تفصیل کیسے لکھیں۔

آپ کے مواد کی تفصیل میں مواد کی مختصر وضاحت ہونی چاہیے۔ مقصد یا کارروائی یہ اس کی بصری شکل کے بجائے ایک عنصر کی خصوصیت ہے۔

// Descriptive, action-oriented label
IconButton(onClick = { deleteDraft() }) {
    Icon(
        imageVector = Icons.Default.Delete,
        contentDescription = "Delete draft message"
    )
}

// Contextual weather information
Image(
    painter = painterResource(R.drawable.weather_sunny),
    contentDescription = "Current weather: Sunny, 75 degrees Fahrenheit"
)

آئیکن کی تفصیل صارفین کو بتاتی ہے کہ جب وہ بٹن کو تھپتھپاتے ہیں تو کیا ہوتا ہے ("مسودہ پیغام حذف کریں”)۔ موسم کی تصاویر آرٹ اسٹائل کی عکاسی کرنے کے بجائے حقیقی بنیادی ڈیٹا فراہم کرتی ہیں۔

کیا نہیں کرنا ہے (اینٹی پیٹرن)

// Avoid generic or redundant descriptions
IconButton(onClick = { deleteDraft() }) {
    Icon(
        imageVector = Icons.Default.Delete,
        contentDescription = "Trash can icon button" // Bad: includes visual style and element type
    )
}

// Avoid empty strings on interactive elements
IconButton(onClick = { openSettings() }) {
    Icon(
        imageVector = Icons.Default.Settings,
        contentDescription = "" // Bad: leaves the button with no accessible label
    )
}

کیونکہ ٹاک بیک پہلے ہی جزو کے کردار کا اعلان کر دیتا ہے، بشمول ‘آئیکن’ یا ‘بٹن’ جیسے الفاظ بے کار ہیں۔ ایک خالی تار استعمال کریں ("") ایک انٹرایکٹو عنصر کے لیے، TalkBack میں کوئی بامعنی اطلاعی مواد نہیں بچا ہے (اسے عام طور پر بغیر لیبل والے بٹن کے طور پر پڑھا جائے گا)، اسکرین ریڈر کے صارفین کو بٹن کے کام کے بارے میں کوئی سیاق و سباق نہیں ملتا۔ کمپوز کا ایکسیسبیلٹی چیکر خالی مواد کی تفصیل کو گمشدہ تفصیلات جیسا ہی سمجھتا ہے۔

کم از کم ٹچ ٹارگٹ سائز کی ضمانت کیسے دی جائے۔

گوگل کے میٹریل ڈیزائن اور اینڈرائیڈ ایکسیسبیلٹی گائیڈ لائنز کے مطابق، تمام انٹرایکٹو عناصر کے لیے کم از کم ٹچ ٹارگٹ سائز 48dp x 48dpیہ تقریباً 9 ملی میٹر کے جسمانی سائز کے مساوی ہے۔ یہ 7-10 ملی میٹر کی حد کے اندر ہے جسے گوگل ٹچ اسکرین اہداف کے لیے تجویز کرتا ہے۔

موازنہ کے مقاصد کے لیے، WCAG خود ایک کم ویب پر مبنی بار سیٹ کرتا ہے۔ WCAG 2.1 کامیابی کے معیار 2.5.5 کو AAA سطح پر 44×44 CSS پکسلز کی ضرورت ہے، اور WCAG 2.2 کامیابی کے معیار 2.5.8 کو AA سطح پر 24×24 CSS پکسلز کی ضرورت ہے۔ 48dp اصول اینڈرائیڈ کا زیادہ سخت پلیٹ فارم معیار ہے۔

// Method A: Using minimumInteractiveComponentSize()
Box(
    modifier = Modifier
        .minimumInteractiveComponentSize() // Expands touch area to 48dp x 48dp
        .clickable { /* Toggle bookmark */ }
) {
    Icon(
        imageVector = Icons.Default.Bookmark,
        contentDescription = "Bookmark article",
        modifier = Modifier.size(24.dp) // Visual size is 24dp, touch target is 48dp
    )
}

// Method B: Standard IconButton (built-in 48dp target)
IconButton(onClick = { /* Toggle bookmark */ }) {
    Icon(
        imageVector = Icons.Default.Bookmark,
        contentDescription = "Bookmark article"
    )
}

Modifier.minimumInteractiveComponentSize() غیر مرئی، قابل کلک ہٹ باکسز کو 48dp × 48dp تک پھیلانے کی اجازت دیتے ہوئے بصری ڈیزائن کو کمپیکٹ رکھیں (مثلاً 24dp آئیکنز)۔ یہ موٹر کے جھٹکے یا محدود باریک موٹر کنٹرول والے صارفین کو چھونے سے روکتا ہے۔

کیا نہیں کرنا ہے (اینٹی پیٹرن)

// Bad: Tightly constrained 20dp clickable area
Icon(
    imageVector = Icons.Default.Close,
    contentDescription = "Close dialog",
    modifier = Modifier
        .size(20.dp)
        .clickable { dismissDialog() } // Touch target is strictly 20dp x 20dp!
)

20dp ٹچ ٹارگٹ کو قابل اعتماد طریقے سے ٹیپ کرنا تقریباً ناممکن ہے، خاص طور پر زیادہ کثافت والے ڈسپلے پر یا چلتے وقت۔ گوگل کا ایکسیسبیلٹی چیکر اسے ٹچ ٹارگٹ ایشو کے طور پر جھنڈا دیتا ہے۔

قابل رسائی رنگ کنٹراسٹ تناسب کو کیسے برقرار رکھا جائے۔

کلر کنٹراسٹ پیش منظر کے متن اور پس منظر کے درمیان روشنی کے فرق کی پیمائش کرتا ہے۔ اگر متضاد تناسب بہت کم ہے تو، کم بینائی، رنگ اندھا پن، یا پریسبیوپیا والے لوگ متن کو پڑھنے کے قابل نہیں ہوں گے۔

WCAG 2.1 مندرجہ ذیل کم از کم کنٹراسٹ تناسب کی وضاحت کرتا ہے: اینڈرائیڈ کی ایکسیسبیلٹی دستاویزات WCAG میں پوائنٹ کے سائز کو مندرجہ ذیل طور پر بیان کرتی ہیں: sp):

  • سادہ متن (18sp سے کم یا 14sp سے کم بولڈ): کم از کم 4.5:1

  • بڑا متن (18sp یا اس سے بڑا یا 14sp بولڈ یا بڑا): کم از کم 3.0:1

  • UI اجزاء اور گرافیکل اشیاء: کم از کم 3.0:1

// Using Material 3 color tokens (paired roles maintain usable contrast)
Text(
    text = "Account Overview",
    color = MaterialTheme.colorScheme.onPrimaryContainer,
    modifier = Modifier.background(MaterialTheme.colorScheme.primaryContainer)
)

// Explicit high-contrast colors (for example, Black on White = 21:1 ratio)
Text(
    text = "Order Confirmed",
    color = Color(0xFF1B5E20), // Dark green
    modifier = Modifier.background(Color(0xFFE8F5E9)) // Light green tint
)

مواد 3 رنگین ٹوکنز، جیسے onPrimaryContainer کے ساتھ جوڑا primaryContainer) مٹیریل کلر سسٹم کے ذریعہ تیار کیا گیا ہے، لہذا "آن” رنگ کنٹینر کے رنگ کے ساتھ دستیاب کنٹراسٹ کو برقرار رکھتا ہے جسے ہلکے اور گہرے دونوں تھیمز میں جوڑا جاتا ہے۔ آپ کو کسی بھی حسب ضرورت برانڈ کے رنگوں کے لیے کنٹراسٹ چیک کرنے کی ضرورت ہوگی۔

کیا نہیں کرنا ہے (اینٹی پیٹرن)

// Bad: Light gray on pure white (Contrast ratio ~ 1.6:1 - Fails WCAG)
Text(
    text = "Terms and Conditions apply",
    color = Color(0xFFB0B0B0),
    modifier = Modifier.background(Color.White)
)

سفید پس منظر پر ہلکا بھوری رنگ کا متن موبائل ویب اور مقامی ایپس پر سب سے زیادہ عام رسائی کی خلاف ورزیوں میں سے ایک ہے۔ روشن محیطی روشنی میں، بصارت والے اور کم بصارت استعمال کرنے والے اس متن کو نہیں پڑھ سکتے۔

حسب ضرورت کلک کے قابل لیبل کیسے فراہم کریں۔

جب کوئی صارف قابل کلک عنصر پر نیویگیٹ کرنے کے لیے TalkBack کا استعمال کرتا ہے، تو اسکرین ریڈر درج ذیل ڈیفالٹ ہدایات شامل کرتا ہے: "فعال کرنے کے لیے دو بار تھپتھپائیں۔”

آپ ان ہدایات کو استعمال کرکے اپنی مرضی کے مطابق کرسکتے ہیں: onClickLabel پیرامیٹر Modifier.clickable تعامل کا صحیح نتیجہ بیان کرتا ہے۔

ListItem(
    headlineContent = { Text("Wi-Fi Networks") },
    supportingContent = { Text("Connected to Office_5G") },
    modifier = Modifier.clickable(
        onClickLabel = "Open Wi-Fi network settings"
    ) {
        navigateToWifiSettings()
    }
)

TalkBack آپ کو درج ذیل بتاتا ہے: "Wi-Fi نیٹ ورک، Office_5G سے منسلک، Wi-Fi نیٹ ورک کی ترتیبات کو کھولنے کے لیے دو بار تھپتھپائیں۔” عمل کرنے سے پہلے صارفین بخوبی جانتے ہیں کہ کیا ہوگا۔

کیا نہیں کرنا ہے (اینٹی پیٹرن)

// Bad: Generic clickable element without context
Card(
    modifier = Modifier.clickable { openInvoiceDetails() }
) {
    Text("Invoice #4092")
}

TalkBack درج ذیل کا اعلان کرتا ہے: "انوائس #4092، چالو کرنے کے لیے دو بار تھپتھپائیں۔” صارفین اس بات کا یقین نہیں کر سکتے کہ آیا بل ادا کرنے کے لیے ٹیپ کرنا ہے، پی ڈی ایف ڈاؤن لوڈ کرنا ہے، یا ایڈیٹنگ اسکرین کھولنا ہے۔

عنوان کا درجہ بندی کیسے ترتیب دی جائے۔

بصری قارئین اسکرین کی ترتیب اور درجہ بندی کو سمجھنے کے لیے بڑے، بولڈ ٹیکسٹ ہیڈنگز کو اسکین کرتے ہیں۔ اسکرین ریڈر کے صارفین کو اسی ساختی جائزہ کی ضرورت ہے۔

درخواست دے کر heading() سیمنٹک موڈیفائر ٹیکسٹ نوڈ کو ایک قابل رسائی عنوان کے طور پر متعین کرتا ہے۔ ٹاک بیک صارفین نیویگیشن موڈ کو ‘ٹائٹل’ میں تبدیل کر سکتے ہیں اور سیکشنز کے درمیان جانے کے لیے تیزی سے اوپر یا نیچے سوائپ کر سکتے ہیں۔

Column(modifier = Modifier.padding(16.dp)) {
    // Screen title heading
    Text(
        text = "Security Settings",
        style = MaterialTheme.typography.headlineMedium,
        modifier = Modifier.semantics { heading() }
    )

    Spacer(modifier = Modifier.height(16.dp))

    // Section 1 heading
    Text(
        text = "Two-Factor Authentication",
        style = MaterialTheme.typography.titleMedium,
        modifier = Modifier.semantics { heading() }
    )
    
    // Section 1 content...

    Spacer(modifier = Modifier.height(16.dp))

    // Section 2 heading
    Text(
        text = "Connected Devices",
        style = MaterialTheme.typography.titleMedium,
        modifier = Modifier.semantics { heading() }
    )
    
    // Section 2 content...
}

TalkBack کے صارفین درجنوں انفرادی سوئچز اور ہدایات کو نظرانداز کرتے ہوئے سیکنڈوں میں براہ راست "کنیکٹڈ ڈیوائسز” پر جا سکتے ہیں۔

کیا نہیں کرنا ہے (اینٹی پیٹرن)

// Bad: Visual heading without semantic markup
Text(
    text = "Two-Factor Authentication",
    style = MaterialTheme.typography.titleLarge // Visually large, but invisible as a heading to TalkBack
)

بغیر semantics { heading() }TalkBack متن کو سادہ باڈی کاپی کے طور پر دیکھتا ہے، صارفین کو عنوان کے مطابق نیویگیٹ کرنے سے روکتا ہے۔

لائیو زونز میں متحرک اپ ڈیٹس کا اعلان کیسے کریں۔

جب اسکرین پر موجود مواد متضاد طور پر اپ ڈیٹ ہوتا ہے (مثال کے طور پر، ٹائمر کاؤنٹ ڈاؤن، فائل اپ لوڈ مکمل کرنے کا پیغام، یا ریئل ٹائم توثیق بینر)، نظر آنے والے صارفین فوری طور پر تبدیلیاں دیکھ سکتے ہیں۔

تاہم، اسکرین ریڈر کے صارفین کو معلوم نہیں ہوگا کہ کیا تبدیلی ہوئی ہے جب تک کہ آپ تبدیلی والے کنٹینر کو بطور نشان زد نہ کریں: زندہ علاقہ.

کمپوز کے ذریعہ تقویت یافتہ liveRegion = LiveRegionMode.Polite اور liveRegion = LiveRegionMode.Assertive:

  • LiveRegionMode.Polite: TalkBack اپ ڈیٹس پڑھنے سے پہلے موجودہ آڈیو اعلان کے ختم ہونے کا انتظار کرتا ہے۔ اس فیچر کو تقریباً کسی بھی اسٹیٹس اپ ڈیٹ کے لیے استعمال کریں۔

  • LiveRegionMode.Assertive: ٹاک بیک آپ کو کسی بھی دوسرے تاثرات سے پہلے تبدیلیوں کی اطلاع دیتا ہے۔ وقت کے لحاظ سے حساس اور فوری انتباہات (جیسے ہنگامی انتباہات) کے لیے سختی سے محفوظ رکھیں۔

var uploadStatus by remember { mutableStateOf("Ready to upload") }

Text(
    text = uploadStatus,
    modifier = Modifier.semantics {
        liveRegion = LiveRegionMode.Polite
    }
)

// Later, when upload finishes:
LaunchedEffect(Unit) {
    performUpload()
    uploadStatus = "Upload complete! 12 files saved."
}

جیسے ہی uploadStatus تبدیلی کریں اور TalkBack خود بخود بولے گا۔ "اپ لوڈ مکمل! 12 فائلیں محفوظ ہو گئیں۔” بصارت سے محروم صارفین کو اسکرین کو تلاش کیے بغیر مکمل معلومات فراہم کرتا ہے۔

متحرک متن کا سائز تبدیل کرنے کی حمایت کیسے کریں۔

کم بصارت والے صارفین اکثر اینڈرائیڈ سیٹنگز (نیچے) میں سسٹم فونٹ کا سائز بڑھا دیتے ہیں۔ نشان یا آپ کے آلے کے لحاظ سے رسائی کی ترتیبات)۔ اینڈرائیڈ 14 اور اس سے اوپر کو سپورٹ کرتا ہے۔ غیر لکیری فونٹ سائز 200% تک.

اس صارف کی ترجیح کا احترام کرنے کے لیے، آپ کو متن کے تمام سائز کی وضاحت اس میں کرنی ہوگی: sp (اسکیل سے آزاد پکسلز)کبھی نہیں dp یا خام پکسلز۔

// Good: Using Material Typography (uses sp automatically)
Text(
    text = "Dashboard Summary",
    style = MaterialTheme.typography.titleMedium
)

// Good: Explicit sp sizing
Text(
    text = "Custom Label",
    fontSize = 18.sp
)

اگر صارف فونٹ کا سائز 1.5× پر سیٹ کرتا ہے، تو 18sp فونٹ صاف طور پر 27sp کے طور پر رینڈر ہو جائے گا، جس سے متن پڑھنے کے قابل ہو جائے گا۔

کیا نہیں کرنا ہے (اینٹی پیٹرن)

// Bad: Fixed dp size converted to sp (does not scale with system settings)
Text(
    text = "Fixed Size Warning",
    fontSize = with(LocalDensity.current) { 16.dp.toSp() } // Will not scale!
)

فکسڈ ٹیکسٹ سائز ایڈجسٹمنٹ dp جب صارف سسٹم فونٹ کا سائز بڑھاتا ہے تو پیمائش متن کو وسعت دینے سے روک کر رسائی کے معیارات کی براہ راست خلاف ورزی کرتی ہے۔

اعلی درجے کی رسائی کی ٹیکنالوجیز

پیچیدہ، پروڈکشن گریڈ ایپلی کیشنز کے لیے، آپ صارف کے اہم تعاملات کو سنبھالنے کے لیے اعلیٰ درجے کی قابل رسائی ٹیکنالوجیز کا اطلاق کر سکتے ہیں۔

ٹراورسل اور فوکس آرڈر کو کیسے کنٹرول کریں۔

پہلے سے طے شدہ طور پر، رسائی کی خدمات بصری اور ساختی نقاط (اوپر سے نیچے، شروع سے آخر تک) کی بنیاد پر اسکرین عناصر پر جاتی ہیں۔ ملٹی کالم لے آؤٹس، فنانشل لیجرز، یا حسب ضرورت گرڈز میں، یہ ڈیفالٹ آرڈر مبہم نوٹس بنا سکتا ہے۔

آپ نیویگیشن آرڈر کو اپنی مرضی کے مطابق بنا سکتے ہیں: traversalIndex اور isTraversalGroup:

Column(
    modifier = Modifier.semantics { isTraversalGroup = true }
) {
    Text(
        text = "Step 1: Account Info",
        modifier = Modifier.semantics { traversalIndex = 1f }
    )
    
    Text(
        text = "Step 3: Confirmation",
        modifier = Modifier.semantics { traversalIndex = 3f }
    )
    
    Text(
        text = "Step 2: Payment Details",
        modifier = Modifier.semantics { traversalIndex = 2f }
    )
}

کوڈ اندرونی طور پر کیسے کام کرتا ہے:

  1. ماحول isTraversalGroup = true ایک خودمختار ایکسیسبیلٹی باؤنڈری بناتا ہے، جو ٹاک بیک کو اسکرین کے دیگر عناصر پر جانے سے پہلے اس کنٹینر کے اندر موجود تمام عناصر کو پڑھنے پر مجبور کرتی ہے۔

  2. کہ traversalIndex فلوٹنگ پوائنٹ کی قدریں درست رشتہ دار ترتیب قائم کرتی ہیں (سب سے کم انڈیکس پہلے)۔ TalkBack ترتیب میں ان کی بصری جگہ سے قطع نظر، 1، 2، اور آخر میں 3 کو پڑھتا ہے۔

حسب ضرورت ایکسیسبیلٹی ایکشنز کیسے بنائیں

ایک ای کامرس پروڈکٹ کارڈ پر غور کریں جس میں "کوئیک ویو”، "اشتہاری فہرست میں شامل کریں” اور "کارٹ میں شامل کریں” کے بٹن شامل ہوں۔ اسکرین ریڈر صارفین کے لیے، لگاتار 20 کارڈز پر تین الگ الگ بٹنوں کو ٹیپ کرنا ایک مشکل کام ہے۔

کے ساتھ customActionsآپ کو ثانوی کارروائیوں کو براہ راست پیرنٹ کارڈ نوڈ سے منسلک کرنے کی اجازت دیتا ہے۔ جب کارڈ پر فوکس کیا جاتا ہے، تو TalkBack صارف کو مطلع کرتا ہے کہ ایک کارروائی دستیاب ہے اور صارف کارروائی کو منتخب کرنے کے لیے TalkBack مینو کھولتا ہے۔

var isBookmarked by remember { mutableStateOf(false) }

Card(
    modifier = Modifier
        .fillMaxWidth()
        .semantics {
            customActions = listOf(
                CustomAccessibilityAction(
                    label = if (isBookmarked) "Remove from bookmarks" else "Add to bookmarks",
                    action = {
                        isBookmarked = !isBookmarked
                        true // Return true to indicate the action was handled
                    }
                ),
                CustomAccessibilityAction(
                    label = "Share article link",
                    action = {
                        shareArticle()
                        true
                    }
                )
            )
        }
) {
    // Visual card content...
}

جب ٹاک بیک صارف کارڈ پر فوکس کرتا ہے تو ٹاک بیک انہیں مطلع کرتا ہے کہ ایک حسب ضرورت کارروائی دستیاب ہے۔ صارفین ٹاک بیک مینو کھولتے ہیں یا ایک صاف ستھرا فہرست دیکھنے کے لیے قابل رسائی کارروائیوں کا استعمال کرتے ہیں جس میں ‘بک مارکس میں شامل کریں’ اور ‘دستاویز کا لنک شیئر کریں’ شامل ہیں۔ یہ بجلی کے صارفین کے لیے براہ راست اور موثر نیویگیشن فراہم کرتے ہوئے بصری ڈیزائن کو آسان بناتا ہے۔

قابل رسائی فارم ان پٹ اور ٹیکسٹ فیلڈز کو کیسے ڈیزائن کریں۔

قابل رسائی فارم ان پٹ کو بصری پلیس ہولڈرز سے زیادہ درکار ہے۔ اس کے لیے واضح لیبلز، واضح ان پٹ قسم کے اشارے، اور منطقی کی بورڈ نیویگیشن درکار ہے۔

var emailValue by remember { mutableStateOf("") }

OutlinedTextField(
    value = emailValue,
    onValueChange = { emailValue = it },
    label = { Text("Work Email") },
    placeholder = { Text("alex@example.com") },
    singleLine = true,
    keyboardOptions = KeyboardOptions(
        keyboardType = KeyboardType.Email,
        imeAction = ImeAction.Next
    ),
    keyboardActions = KeyboardActions(
        onNext = { /* Move focus to password field */ }
    ),
    modifier = Modifier
        .fillMaxWidth()
        .semantics {
            contentDescription = "Work email address input field"
        }
)

یہ اندرونی طور پر کیسے کام کرتا ہے:

  • کہ label کمپوز ایبلز مستقل سیاق و سباق فراہم کرتے ہیں جو صارف کے ان پٹ کے بعد بھی نظر آتا ہے۔

  • keyboardType = KeyboardType.Email اینڈروئیڈ کو ای میل (شامل) کے لیے موزوں کی بورڈ ڈسپلے کرنے کی ہدایت کرتا ہے۔ @ اور .com شارٹ کٹ) اور معیاری ای میل نحو قابل رسائی خدمات کے لیے اشارے فراہم کرتے ہیں جن کی ضرورت ہوتی ہے۔

  • imeAction = ImeAction.Next ہارڈ ویئر کی بورڈ صارفین کو قابل بناتا ہے اور آلہ کے صارفین کو کی بورڈ Enter کلید استعمال کرنے کے لیے سوئچ کرتا ہے تاکہ فارم فیلڈز کے ذریعے بغیر کسی رکاوٹ کے آگے بڑھ سکے۔

متحرک خرابی کے حالات سے کیسے بات چیت کریں۔

اگر کلائنٹ سائیڈ کی توثیق ناکام ہوجاتی ہے، تو بصری بارڈر کو سرخ پر سیٹ کرنا کافی نہیں ہے۔ سیمنٹک ایرر میٹا ڈیٹا کو منسلک کرنا ضروری ہے تاکہ اسکرین ریڈرز کو توثیق کی ناکامی کے بارے میں فوری طور پر مطلع کیا جائے۔

var password by remember { mutableStateOf("") }
val isPasswordInvalid = password.isNotEmpty() && password.length < 8

OutlinedTextField(
    value = password,
    onValueChange = { password = it },
    label = { Text("Password") },
    isError = isPasswordInvalid,
    supportingText = {
        if (isPasswordInvalid) {
            Text(
                text = "Password must be at least 8 characters long",
                color = MaterialTheme.colorScheme.error
            )
        }
    },
    modifier = Modifier
        .fillMaxWidth()
        .semantics {
            if (isPasswordInvalid) {
                error("Password must be at least 8 characters long")
            }
        }
)

یہ اندرونی طور پر کیسے کام کرتا ہے:

کہ isError = isPasswordInvalid پیرامیٹرز بصری انداز کو ہینڈل کرتے ہیں (سرخ خاکہ اور ایرر آئیکن)۔

  • کہ error("...") سیمنٹک انتساب ٹاک بیک کو ہدایت دیتا ہے کہ وہ اس عنصر کو غلط سمجھے اور جیسے ہی صارف ٹیکسٹ فیلڈ پر فوکس کرتا ہے توثیق کی ایک مخصوص خرابی کا پیغام دیتا ہے۔

ترقی کے اشارے اور غیر مطابقت پذیر لوڈنگ کا انتظام کیسے کریں۔

لوڈنگ سٹیٹس کو واضح طور پر بتانا چاہیے کہ آیا کام غیر متعین ہے (نامعلوم مدت کے لیے آگے بڑھ رہا ہے) یا تصدیق شدہ (100% کی طرف بڑھ رہا ہے)۔

// Indeterminate Progress (such as initial network fetch)
CircularProgressIndicator(
    modifier = Modifier.semantics {
        contentDescription = "Syncing messages, please wait"
    }
)

// Determinate Progress (such as file download)
val downloadProgress = 0.65f // 65%

LinearProgressIndicator(
    progress = { downloadProgress },
    modifier = Modifier.semantics {
        progressBarRangeInfo = ProgressBarRangeInfo(
            current = downloadProgress,
            range = 0f..1f
        )
        contentDescription = "Downloading update: ${(downloadProgress * 100).toInt()}% completed"
    }
)

ٹھوس ترقی کے اشارے کے لیے، ProgressBarRangeInfo کم از کم، زیادہ سے زیادہ، اور موجودہ اقدار کی معاون ٹیکنالوجی سے آگاہ کرتا ہے۔ TalkBack اس معلومات کی ترجمانی کرتا ہے اور آپ کی پیشرفت کی بنیاد پر وقتاً فوقتاً قابل سماعت اور ٹچائل اپ ڈیٹس فراہم کرتا ہے۔

قابل توسیع اور ٹوٹنے کے قابل مواد کو کیسے ہینڈل کریں۔

Accordion مینو اور توسیعی FAQ کارڈز کو واضح طور پر بتانا چاہیے کہ آیا وہ کھلے ہیں یا بند ہیں اور ٹیپ کرنے پر وہ کیا کارروائی کرتے ہیں۔

var isExpanded by remember { mutableStateOf(false) }

Column(modifier = Modifier.fillMaxWidth()) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        modifier = Modifier
            .fillMaxWidth()
            .clickable(
                onClickLabel = if (isExpanded) "Collapse section" else "Expand section"
            ) {
                isExpanded = !isExpanded
            }
            .semantics {
                stateDescription = if (isExpanded) "Expanded" else "Collapsed"
            }
            .padding(16.dp)
    ) {
        Text(
            text = "Frequently Asked Questions",
            style = MaterialTheme.typography.titleMedium,
            modifier = Modifier.weight(1f)
        )
        Icon(
            imageVector = if (isExpanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore,
            contentDescription = null // Decorative: parent Row communicates full state
        )
    }

    AnimatedVisibility(visible = isExpanded) {
        Text(
            text = "Our refund policy allows returns within 30 days of purchase...",
            modifier = Modifier.padding(16.dp)
        )
    }
}

کہ stateDescription اشارہ کرتا ہے کہ آیا سیکشن فی الحال کھلا ہے یا بند ہے ("توسیع شدہ" یا "منتشر")۔ ایک ہی وقت میں، onClickLabel مطلوبہ کارروائی کو واضح کریں ("سیکشن کو ختم کریں" یا "سیکشن کو بڑھا دیں")۔ آئیکن میں contentDescription = null ڈپلیکیٹ نوٹس سے بچنے کے لیے۔

سست فہرستوں اور بڑے مجموعوں کو کیسے بہتر بنایا جائے۔

جب صارفین لمبی فیڈز یا فہرستوں کو نیویگیٹ کرتے ہیں، تو انہیں اس بارے میں سیاق و سباق کی ضرورت ہوتی ہے کہ وہ کہاں ہیں اور ان کے پاس کتنے آئٹمز ہیں۔

val messages = remember { listOf("Order Shipped", "Delivery Delayed", "Payment Received") }

LazyColumn(
    modifier = Modifier.semantics {
        contentDescription = "Notifications list, ${messages.size} total alerts"
    }
) {
    itemsIndexed(messages) { index, messageText ->
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(vertical = 4.dp)
                .semantics {
                    contentDescription = "Notification ${index + 1} of ${messages.size}: $messageText"
                }
        ) {
            Text(
                text = messageText,
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}

TalkBack ایک لوکیشن انڈیکس جاری کر رہا ہے ("3 میں سے 1 نوٹیفکیشن: آرڈر بھیج دیا گیا") تاکہ اسکرین ریڈر صارفین کو اپنا مقام کھونے کے بغیر فہرست میں اپنی پیشرفت کو ٹریک کرنے میں مدد ملے۔

رسائی کی جانچ اور ڈیبگ کرنے کا طریقہ

قابل رسائی سافٹ ویئر بنانے کے لیے کثیر پرتوں والی جانچ کی حکمت عملی کی ضرورت ہوتی ہے، بشمول خودکار ریگریشن ٹیسٹنگ، آن ڈیوائس تشخیصی ٹولز، سیمنٹک ٹری چیکنگ، اور TalkBack کے ساتھ دستی تصدیق۔

ٹیسٹ کی سطح بنیادی اوزار جو اس کی تصدیق کرتا ہے۔ کب دوڑنا ہے۔
دستی تصدیق ٹاک بیک اسکرین ریڈر حقیقی دنیا کا غیر بصری صارف کا تجربہ اور اشارہ نیویگیشن اہم خصوصیات جاری ہونے سے پہلے
بصری تعریف گوگل ایکسیسبیلٹی اسکینر خودکار اسکرین کنٹراسٹ اور ٹچ ٹارگٹ کی خلاف ورزیاں فنکشنل QA ٹیسٹنگ جاری ہے۔
درخت کا معائنہ اینڈرائیڈ اسٹوڈیو لے آؤٹ انسپکٹر ریئل ٹائم سیمنٹک ٹری کا انضمام اور نوڈ کی خصوصیات فعال ترقی میں
خودکار معائنہ UI ٹیسٹ لکھیں (ui-test-junit4) رابطے کے اہداف اور مواد کی تفصیل پر رجعت مسلسل انضمام (CI)

ٹاک بیک کا استعمال کرتے ہوئے دستی طور پر ٹیسٹ کرنے کا طریقہ

TalkBack کا استعمال کرتے ہوئے ایپلیکیشنز کو دستی طور پر نیویگیٹ کرنے کا کوئی متبادل نہیں ہے۔

TalkBack کو کیسے فعال اور استعمال کریں۔

  1. اپنا آلہ کھولیں۔ ترتیب ایپ کھولیں اور اس پر جائیں: رسائی پھر ٹاک بیک.

  2. سوئچ کو اس پر پلٹائیں: کو سسٹم کی اجازتیں قبول کریں۔ (اگر فعال ہو تو، آپ والیوم کلید کے شارٹ کٹس بھی استعمال کر سکتے ہیں۔ TalkBack کو ٹوگل کرنے کے لیے، دونوں والیوم کیز کو چند سیکنڈ کے لیے دبائیں)

  3. بنیادی TalkBack سلوک:

    • دائیں سوائپ کریں: ایکسیسبیلٹی فوکس کو اگلے عنصر پر منتقل کریں۔

    • بائیں سوائپ کریں: ایکسیسبیلٹی فوکس کو پچھلے عنصر کی طرف لے جاتی ہے۔

    • دو بار تھپتھپائیں: موجودہ فوکس کردہ عنصر کو چالو کرتا ہے۔

    • دو انگلیوں سے سوائپ: فہرست یا صفحہ کے ذریعے سکرول کریں۔

    • تین انگلیوں سے تھپتھپائیں (یا نیچے سوائپ کریں اور پھر ایک حرکت میں دائیں): TalkBack مینو کھولیں۔

TalkBack پریکٹس کے دوران چیک کرنے کی چیزیں:

  • کیا آپ آنکھیں بند کر کے صارف کے اہم سفر (جیسے رجسٹریشن، لاگ ان، تلاش، چیک آؤٹ) مکمل کر سکتے ہیں؟

  • کیا تمام بٹن اور انٹرایکٹو کنٹرولز پر واضح طور پر معنی خیز ناموں کا لیبل لگا ہوا ہے؟

  • کیا توجہ ایک منطقی اور متوقع پڑھنے کی ترتیب کی طرف جاتی ہے؟

  • کیا غلطی کے پیغامات اور متحرک حالت کی تبدیلیاں خود بخود مطلع ہوجاتی ہیں؟

خودکار تحریر تک رسائی کے ٹیسٹ کیسے لکھیں۔

آپ کے مسلسل انضمام (CI) سرور میں گم شدہ تفصیل اور کم سائز کے ٹچ اہداف کو پکڑنے کے لیے اپنے JUnit انسٹرومینٹیشن ٹیسٹوں میں خودکار رسائی کے دعووں کو ضم کریں۔

انحصار شامل کریں۔ build.gradle.kts:

androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation("androidx.compose.ui:ui-test-manifest")

کمپوز ایکسیسبیلٹی ٹیسٹ لکھیں:

@RunWith(AndroidJUnit4::class)
class AccessibilityTest {

    @get:Rule
    val composeTestRule = createAndroidComposeRule()

    @Test
    fun testLoginButton_hasProperTouchTargetAndLabel() {
        composeTestRule.setContent {
            MaterialTheme {
                Button(
                    onClick = { /* Submit login */ },
                    modifier = Modifier.minimumInteractiveComponentSize()
                ) {
                    Text("Sign In")
                }
            }
        }

        // Verify the node exists with correct text and semantics
        composeTestRule
            .onNodeWithText("Sign In")
            .assertExists()
            .assertHasClickAction()
            .assertHeightIsAtLeast(48.dp)
            .assertWidthIsAtLeast(48.dp)
    }

    @Test
    fun testIconButton_containsContentDescription() {
        composeTestRule.setContent {
            MaterialTheme {
                IconButton(onClick = {}) {
                    Icon(
                        imageVector = Icons.Default.Favorite,
                        contentDescription = "Add to favorites"
                    )
                }
            }
        }

        // Verify content description is accurately exposed in semantics tree
        composeTestRule
            .onNode(hasContentDescription("Add to favorites"))
            .assertExists()
            .assertHasClickAction()
    }
}

Google Accessibility Checker مرحلہ وار گائیڈ

گوگل ایکسیسبیلٹی اسکینر ایک Android تشخیصی ٹول جو آپ کی ایپ کے پیش کردہ UI کا معائنہ کرتا ہے اور ایکسیسبیلٹی کی خلاف ورزیوں کو جھنڈا دیتا ہے۔

ایکسیسبیلٹی چیکر کو انسٹال اور سیٹ اپ کرنے کا طریقہ

  1. گوگل پلے سے انسٹال کریں: اپنے ٹیسٹ ڈیوائس پر گوگل پلے اسٹور کھولیں اور اسے انسٹال کریں۔ قابل رسائی سکینر (Google LLC کے ذریعہ شائع کردہ)۔

  2. رسائی کی ترتیبات میں فعال کریں:

  3. تیرتے بٹن کو تلاش کریں: چیک مارک آئیکن کے ساتھ بلیو فلوٹنگ ایکشن بٹن (✓) یہ اسکرین پر ایک اوورلے کے طور پر ظاہر ہوتا ہے۔

اسکین چلانا اور نتائج کی ترجمانی کرنا

اپنی اینڈرائیڈ ایپلیکیشن کھولیں اور اس اسکرین پر جائیں جس کا آپ آڈٹ کرنا چاہتے ہیں۔ تیرتے نیلے کو تھپتھپائیں۔ سکینر بٹن.

پھر سنیپ شاٹ جامد اسکرین کا تجزیہ کرنے کے لیے (کیمرہ) آئیکن کو تھپتھپائیں۔ ریکارڈ متعدد قدمی صارف کے بہاؤ کا آڈٹ کریں۔

سکینر ہر جھنڈے والے UI جزو کا پتہ لگاتا ہے۔ اورنج مستطیل. عام نتائج میں 48dp سے چھوٹے انٹرایکٹو ٹچ اہداف، بٹنوں اور تصاویر پر لیبل غائب، متن یا تصویر کے برعکس کی کمی، اور بے کار یا بے کار وضاحتیں شامل ہیں۔

مسئلہ کو بیان کرنے والے تفصیلی تجزیہ، متعلقہ رسائی کے رہنما خطوط کے لنکس، اور تدارک کے تجویز کردہ اقدامات دیکھنے کے لیے ایک نمایاں کردہ نتیجہ کو تھپتھپائیں۔ براہ کرم ذہن میں رکھیں کہ سکینر ایک تشخیصی آلہ ہے۔ کلین اسکین ایپس تک مکمل رسائی کی ضمانت نہیں دیتا۔

تصویر: Google Accessibility Scanner AccessibilityDemo ایپ کا آڈٹ کر رہا ہے، چھوٹے 24dp ٹچ اہداف کو نشان زد کر رہا ہے اور تدارک کی ہدایات دکھا رہا ہے۔

اینڈرائیڈ اسٹوڈیو لے آؤٹ انسپکٹر کا استعمال کرتے ہوئے سیمنٹکس کا معائنہ کیسے کریں۔

اینڈرائیڈ اسٹوڈیو میں لے آؤٹ چیکر آپ ریئل ٹائم میں چلتے ہوئے کمپوز کے درجہ بندی کا معائنہ کر سکتے ہیں اور آپریٹنگ سسٹم کے سامنے آنے والے عین سیمنٹک ٹری کو دیکھ سکتے ہیں۔

مرحلہ وار الفاظ کی جانچ کیسے کریں۔

  1. کمپوز ایپلیکیشن کو USB ڈیبگنگ کے ذریعے منسلک ایمولیٹر یا فزیکل ڈیوائس پر چلائیں۔

  2. اینڈرائیڈ اسٹوڈیو میں، کھولیں: دیکھیں پھر ٹول ونڈو پھر لے آؤٹ چیکر.

  3. پروسیس سلیکٹر ڈراپ ڈاؤن میں، اپنی درخواست میں عمل کو منتخب کریں، جیسے com.example.accessibilitydemo

  4. بائیں طرف لے آؤٹ انسپکٹر جزو درخت کے پینل میں، کمپوز ایبل پر جائیں جس کا آپ معائنہ کرنا چاہتے ہیں، جیسے Card سیمنٹک انضمام میں)۔

  5. دیکھو وصف دائیں پینل۔ آپ کو اس کے لیے مخصوص حصے نظر آئیں گے:

    • ضم شدہ معنی: درج ذیل صورتوں میں قابل رسائی خدمات کے سامنے آنے والے کم سیمنٹک میٹا ڈیٹا کو دکھاتا ہے: mergeDescendants = true استعمال شدہ (انضمام سمیت) ContentDescription, Text جھکاؤ OnClick ٹاسک اور کنٹینر کے جھنڈے)۔

    • اعلان شدہ معنی: کسی مخصوص کنفیگر ایبل نوڈ سے براہ راست منسلک واضح سیمنٹک خصوصیات کو دکھاتا ہے۔

c9d918df-794b-41ff-9771-3ec4b772a5f8

تصویر: AccessibilityDemo ایپ کا معائنہ کرنے والا اینڈرائیڈ اسٹوڈیو لے آؤٹ انسپکٹر بائیں جانب ایک جزو کا درخت، بیچ میں ایک بصری وائر فریم، اور دائیں جانب ضم شدہ سیمنٹکس پراپرٹیز پینل دکھاتا ہے۔

لے آؤٹ انسپکٹر کا استعمال آپ کو درج ذیل بصری تصدیق فراہم کرتا ہے:

  • semantics(mergeDescendants = true) مختلف بچوں کو ایک ہی نوڈ میں مناسب طریقے سے گروپ کریں۔

  • آرائشی آئیکن کو کامیابی کے ساتھ رسائی کے درخت سے خارج کر دیا گیا ہے۔

  • ایکشن پر کلک کریں (OnClick: AccessibilityAction) اور کسٹم ایکشنز کمپوز ایبل سے صحیح طریقے سے منسلک ہیں۔

واقعی قابل رسائی UI پیٹرن

ذیل میں ایک عام UI پیٹرن کا مکمل، پروڈکشن کے لیے تیار نفاذ ہے۔

مکمل طور پر قابل رسائی لاگ ان فارم

فارم ایک اہم داخلی نقطہ ہیں۔ یہ نفاذ عنوان کے الفاظ، ای میل ان پٹ کی توثیق، متحرک غلطی کی اطلاع، اور مناسب ٹچ ٹارگٹ سائزنگ کو یکجا کرتا ہے۔

@Composable
fun AccessibleLoginForm(
    onLoginSubmitted: (String, String) -> Unit
) {
    var email by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    var isSubmitted by remember { mutableStateOf(false) }

    val isEmailInvalid = isSubmitted && !android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches()
    val isPasswordInvalid = isSubmitted && password.length < 8

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp)
    ) {
        // 1. Designated Screen Title Heading
        Text(
            text = "Welcome Back",
            style = MaterialTheme.typography.headlineLarge,
            modifier = Modifier.semantics { heading() }
        )

        Text(
            text = "Sign in to access your account",
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant
        )

        Spacer(modifier = Modifier.height(24.dp))

        // 2. Accessible Email Input
        OutlinedTextField(
            value = email,
            onValueChange = { email = it },
            label = { Text("Email Address") },
            isError = isEmailInvalid,
            singleLine = true,
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Email,
                imeAction = ImeAction.Next
            ),
            supportingText = {
                if (isEmailInvalid) {
                    Text(
                        text = "Please enter a valid email address",
                        color = MaterialTheme.colorScheme.error
                    )
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .semantics {
                    if (isEmailInvalid) {
                        error("Please enter a valid email address")
                    }
                }
        )

        Spacer(modifier = Modifier.height(16.dp))

        // 3. Accessible Password Input
        OutlinedTextField(
            value = password,
            onValueChange = { password = it },
            label = { Text("Password") },
            isError = isPasswordInvalid,
            singleLine = true,
            visualTransformation = PasswordVisualTransformation(),
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Password,
                imeAction = ImeAction.Done
            ),
            supportingText = {
                if (isPasswordInvalid) {
                    Text(
                        text = "Password must be at least 8 characters long",
                        color = MaterialTheme.colorScheme.error
                    )
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .semantics {
                    if (isPasswordInvalid) {
                        error("Password must be at least 8 characters long")
                    }
                }
        )

        Spacer(modifier = Modifier.height(24.dp))

        // 4. Accessible Submit Button
        Button(
            onClick = {
                isSubmitted = true
                if (!isEmailInvalid && !isPasswordInvalid) {
                    onLoginSubmitted(email, password)
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .minimumInteractiveComponentSize()
                .semantics {
                    contentDescription = "Sign in to your account"
                }
        ) {
            Text("Sign In")
        }
    }
}

یہ پیٹرن کیوں کام کرتا ہے:

  1. اسکرین کا عنوان: ٹاک بیک صارفین اسکرین میں داخل ہونے پر فوری طور پر "ویلکم بیک" پر جا سکتے ہیں۔

  2. غلطی کا مطلب: اگر توثیق ناکام ہوجاتی ہے۔ error("...") جب ٹیکسٹ فیلڈ فوکس حاصل کرتا ہے، تو TalkBack فوری طور پر توثیق کے تقاضوں کو بولتا ہے۔

  3. کی بورڈ روٹنگ: ImeAction.Next اور ImeAction.Done کی بورڈ کی رہنمائی کریں اور بغیر کسی رکاوٹ کے صارفین کو ان پٹ فیلڈز کے درمیان منتقل کریں۔

اپنی مرضی کے مطابق کارروائیوں کے ساتھ ای کامرس پروڈکٹ کارڈز

یہ پیٹرن دکھاتا ہے کہ کس طرح اکٹھا کیا جائے: mergeDescendants = true کے ساتھ customActions مختصر اور جدید صارف دوست کارڈ بنانے کے لیے:

data class Product(
    val id: String,
    val title: String,
    val priceFormatted: String,
    val rating: Float,
    val imageRes: Int
)

@Composable
fun AccessibleProductCard(
    product: Product,
    onCardClick: () -> Unit,
    onToggleFavorite: () -> Unit,
    onAddToCart: () -> Unit
) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .clickable(onClickLabel = "View product details") { onCardClick() }
            .semantics(mergeDescendants = true) {
                // Group all descriptive properties into one coherent announcement
                contentDescription = "${product.title}, Price: ${product.priceFormatted}, Rated ${product.rating} out of 5 stars"
                
                // Expose secondary operations as custom accessibility actions
                customActions = listOf(
                    CustomAccessibilityAction("Add to shopping cart") {
                        onAddToCart()
                        true
                    },
                    CustomAccessibilityAction("Save to favorites") {
                        onToggleFavorite()
                        true
                    }
                )
            }
    ) {
        Row(
            modifier = Modifier.padding(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Image(
                painter = painterResource(product.imageRes),
                contentDescription = null, // Decorative: covered by merged description
                modifier = Modifier
                    .size(80.dp)
                    .clip(RoundedCornerShape(8.dp))
            )

            Spacer(modifier = Modifier.width(16.dp))

            Column(modifier = Modifier.weight(1f)) {
                Text(
                    text = product.title,
                    style = MaterialTheme.typography.titleMedium
                )
                Text(
                    text = product.priceFormatted,
                    style = MaterialTheme.typography.bodyLarge,
                    fontWeight = FontWeight.Bold
                )
                Text(
                    text = "★ ${product.rating}",
                    style = MaterialTheme.typography.bodySmall,
                    color = MaterialTheme.colorScheme.onSurfaceVariant
                )
            }
        }
    }
}

یہ پیٹرن کیوں کام کرتا ہے:

  1. سنگل اسٹاپ کا مطلب: علیحدہ تصویر اور ٹیکسٹ ویوز کے ذریعے چار بار سوائپ کرنے کے بجائے، TalkBack پورے کارڈ کو ایک متحد بیان کے طور پر پڑھتا ہے۔

  2. ایکشن شارٹ کٹس: صارفین تفصیلات کے صفحہ پر جانے کے بغیر ٹاک بیک ایکشن مینو سے براہ راست اپنے کارٹ یا پسندیدہ میں آئٹمز شامل کر سکتے ہیں۔

سلیکشن سٹیٹس کا استعمال کرتے ہوئے ٹیب نیویگیشن

یہ پیٹرن ٹیب بار نیویگیشن کو اس کا استعمال کرتے ہوئے قابل رسائی ظاہر کرتا ہے: stateDescription اور حسب ضرورت ٹیب کے اعلانات:

@Composable
fun AccessibleTabNavigation(
    tabs: List,
    selectedTabIndex: Int,
    onTabSelected: (Int) -> Unit
) {
    TabRow(
        selectedTabIndex = selectedTabIndex,
        modifier = Modifier.semantics {
            contentDescription = "Navigation tabs, ${tabs[selectedTabIndex]} selected"
        }
    ) {
        tabs.forEachIndexed { index, title ->
            val isSelected = selectedTabIndex == index
            Tab(
                selected = isSelected,
                onClick = { onTabSelected(index) },
                modifier = Modifier.semantics {
                    role = Role.Tab
                    stateDescription = if (isSelected) "Selected" else "Not selected"
                    contentDescription = "$title tab"
                }
            ) {
                Text(
                    text = title,
                    modifier = Modifier.padding(vertical = 16.dp)
                )
            }
        }
    }
}

یہ پیٹرن کیوں کام کرتا ہے:

  1. واضح کردار: ہر آئٹم کو نشان زد کریں۔ Role.Tab قابل رسائی سروس کو مطلع کرتا ہے کہ یہ ایک قابل انتخاب ٹیب کنٹینر ہے۔

  2. اختیاری تاثرات: کہ stateDescription صارف کے ٹیپ کرنے سے پہلے، یہ صارف کو بتاتا ہے کہ ٹیب فی الحال فعال ہے یا نہیں۔

کارروائی کی تفصیل کے ساتھ تصدیقی ڈائیلاگ

یہ پیٹرن دکھاتا ہے کہ قابل رسائی تصدیقی ڈائیلاگ کیسے بنایا جائے۔

@Composable
fun AccessibleDeleteConfirmationDialog(
    itemName: String,
    onDismissRequest: () -> Unit,
    onConfirmDelete: () -> Unit
) {
    AlertDialog(
        onDismissRequest = onDismissRequest,
        title = {
            Text(
                text = "Delete Item?",
                style = MaterialTheme.typography.headlineSmall,
                modifier = Modifier.semantics { heading() }
            )
        },
        text = {
            Text("Are you sure you want to permanently delete "$itemName"? This action cannot be undone.")
        },
        confirmButton = {
            TextButton(
                onClick = onConfirmDelete,
                modifier = Modifier.semantics {
                    contentDescription = "Confirm deletion of $itemName"
                }
            ) {
                Text("Delete", color = MaterialTheme.colorScheme.error)
            }
        },
        dismissButton = {
            TextButton(
                onClick = onDismissRequest,
                modifier = Modifier.semantics {
                    contentDescription = "Cancel deletion and close dialog"
                }
            ) {
                Text("Cancel")
            }
        },
        modifier = Modifier.semantics {
            contentDescription = "Delete item confirmation dialog"
        }
    )
}

یہ پیٹرن کیوں کام کرتا ہے:

  1. واضح فوکس: جب ایک ڈائیلاگ باکس ظاہر ہوتا ہے، تو TalkBack خود بخود توجہ کو ڈائیلاگ باکس کی حدود میں پھنس دیتا ہے تاکہ صارفین کو غلطی سے پس منظر کے عناصر پر کلک کرنے سے روکا جا سکے۔

  2. سیاق و سباق کے لیے حساس بٹن: بٹن کی تفصیل کلک کے صحیح نتیجے کی وضاحت کرتی ہے (صرف "حذف کریں" کے بجائے "خریداری کی فہرست کو حذف کرنے کی تصدیق کریں")۔

قابل رسائی آڈٹ چیک لسٹ

اپنی ایپ کو پروڈکشن میں جاری کرنے یا اسے ایپ اسٹور پر جمع کرانے سے پہلے، درج ذیل ایکسیسبیلٹی آڈٹ چیک لسٹ کو چلائیں:

بصری اور نوع ٹائپ

  • قابل توسیع متن: تمام فونٹ سائز کی وضاحت کریں۔ sp (کبھی طے نہیں ہوا۔ dp) تو متن صاف طور پر 200٪ تک پیمانہ کرتا ہے۔

  • رنگ کا تضاد: کم از کم 4.5:1 سادہ متن کے لیے تناسب امتزاج اور 3.0:1 پس منظر کے خلاف بڑے متن اور ضروری UI اجزاء ڈسپلے کریں۔

  • رنگ کی آزادی: صرف رنگ کے ذریعے معلومات نہ پہنچائیں۔ متن کے لیبلز یا منفرد شبیہیں کے ساتھ ہمیشہ رنگین اشارے جوڑیں۔

انٹرایکٹو عناصر اور ٹچ اہداف

  • ٹچ ہدف کا سائز تبدیل کریں: اس بات کو یقینی بنائیں کہ ہر کلک کے قابل یا انٹرایکٹو جزو کا کم از کم ہٹ ہدف ہے۔ 48dp x 48dp استعمال کرتے ہوئے Modifier.minimumInteractiveComponentSize().

  • قابل عمل وضاحت: وضاحتی اور عمل پر مبنی ترسیل contentDescription تمام فیچر آئیکن بٹنز اور انٹرایکٹو امیجز کے لیے سٹرنگز۔

  • آرائشی عناصر: سیٹ contentDescription = null TalkBack کے تاثرات کو مختصر رکھنے کے لیے، ہم خالصتاً آرائشی شبیہیں اور عکاسی استعمال کرتے ہیں۔

  • سیاق و سباق پر کلک کریں۔ اپنی مرضی کے مطابق پیشکش onClickLabel ہم کارڈز، فہرست آئٹمز، اور حسب ضرورت بٹنوں کو فعال کرنے سے پہلے نتائج کو واضح کرنے کے لیے پیرامیٹرز فراہم کرتے ہیں۔

اسکرین کی ساخت اور نیویگیشن

  • قابل رسائی عنوان: مین سیکشن کے عنوانات اور اسکرین ہیڈر اس طرح دکھائیں: Modifier.semantics { heading() } فوری سمت تلاش کرنے کے لیے۔

  • سیمنٹک انضمام: گروپ سے متعلقہ بصری ذیلی عناصر کے لیے درج ذیل کا استعمال کریں (جیسے تعریف یا ملٹی ٹیکسٹ کارڈ ہیڈر): Modifier.semantics(mergeDescendants = true).

  • ریئل ٹائم اعلانات: اس کا استعمال کرتے ہوئے غیر مطابقت پذیر UI اپ ڈیٹس کی وضاحت کریں: liveRegion = LiveRegionMode.Polite لہذا TalkBack آپ کو پس منظر میں ہونے والی تبدیلیوں کے بارے میں مطلع کرے گا۔

  • فارم کی اصلاح: مناسب عہدہ keyboardType اور imeAction تمام ٹیکسٹ ان پٹ کے لیے کنفیگریشن۔

  • تصدیقی تاثرات: استعمال کرتے ہوئے ایک فعال ان پٹ ایرر اسٹیٹ کا اعلان کریں: Modifier.semantics { error("...") }.

جانچ اور تصدیق

  • خودکار یونٹ ٹیسٹنگ: رابطے کے اہداف اور گمشدہ لیبل ریگریشنز کو پکڑنے کے لیے مسلسل انضمام میں تحریر تک رسائی کے دعوے شامل کریں۔

  • ڈیوائس پر تشخیصی آڈٹ: کنٹراسٹ یا سائز کے نقائص کو تلاش کرنے کے لیے تمام بڑی ایپ اسکرینوں پر Google Accessibility Checker چلائیں۔

  • سیمنٹک درخت کا معائنہ: ضم شدہ سیمنٹکس اور اعلان کردہ ایکسیسبیلٹی آپریشنز دیکھنے کے لیے اینڈرائیڈ اسٹوڈیو لے آؤٹ انسپکٹر کا استعمال کریں۔

  • دستی اسکرین ریڈر واک تھرو: صارف کا پورا سفر (لاگ ان، ادائیگی، نیویگیشن) مکمل کرنے کے لیے TalkBack کو فعال کریں۔

نتیجہ اور اگلے اقدامات

جیٹ پیک کمپوز میں قابل رسائی ایپلی کیشنز بنانے کا مطلب صرف پراجیکٹ کے اختتام پر کوڈ کو تبدیل کرنا نہیں ہے۔ آپ کو کمپوز کے ڈوئل ٹری آرکیٹیکچر کو سمجھنے اور اپنے صارف انٹرفیس کو ڈیزائن کرنے کی ضرورت ہے تاکہ بصری پکسلز اور سیمنٹک میٹا ڈیٹا دونوں آپ کی درخواست کے ارادے کو درست طریقے سے ظاہر کریں۔

معنوی خصوصیات کو نافذ کر کے، 48dp ٹچ ٹارگٹ کی ضمانت دے کر، WCAG کنٹراسٹ ریشو کو برقرار رکھ کر، اور TalkBack اور Google Accessibility Scanner کے ساتھ اپنے اعمال کی جانچ کر کے، آپ اس بات کو یقینی بناتے ہیں کہ آپ کی Android ایپلیکیشن دنیا بھر کے تمام صارفین کے لیے خوش آئند، مطابقت پذیر، اور استعمال کے لیے بدیہی ہے۔

ضروری وسائل

Android کی رسائی کے بارے میں اپنی سمجھ کو گہرا کرنے کے لیے، یہ ضروری وسائل دیکھیں:

Scroll to Top