تغییر ترتیب پیمایش

ترتیب پیمایش ترتیبی است که خدمات دسترس‌پذیری در آن از میان عناصر واسط کاربر پیمایش می‌کنند. در برنامه «نوشتن»، عناصر به ترتیب خواندن موردانتظار چیده می‌شوند، که معمولاً از راست به چپ، سپس از بالا به پایین است. بااین‌حال، در برخی‌از موقعیت‌ها، «نوشتن» ممکن است برای تعیین ترتیب خواندن صحیح به نشان‌های اضافی نیاز داشته باشد.

isTraversalGroup و traversalIndex دارایی‌های معنایی هستند که به شما امکان می‌دهند بر ترتیب پیمایش برای خدمات دسترس‌پذیری در سناریوهایی که الگوریتم مرتب‌سازی پیش‌فرض Compose کافی نیست تأثیر بگذارید. isTraversalGroup گروه‌های معنایی مهمی را که نیاز به سفارشی‌سازی دارند شناسایی می‌کند، درحالی‌که traversalIndex ترتیب عناصر منفرد را در آن گروه‌ها تنظیم می‌کند. می‌توانید از isTraversalGroup به‌تنهایی استفاده کنید تا نشان دهید همه عناصر درون یک گروه باید باهم انتخاب شوند، یا از آن با traversalIndex برای سفارشی‌سازی بیشتر استفاده کنید.

از isTraversalGroup و traversalIndex در برنامه‌تان برای کنترل ترتیب پیمایش صفحه‌خوان استفاده کنید.

گروه‌بندی عناصر برای پیمایش

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

تنظیم isTraversalGroup = true روی یک گره به این معنی است که همه فرزندان آن گره قبل‌از رفتن به عناصر دیگر بازدید می‌شوند. می‌توانید isTraversalGroup را روی گره‌های قابل‌تمرکز غیرصفحه‌خوان، مثل ستون‌ها، ردیف‌ها، یا چارگوش‌ها تنظیم کنید.

مثال زیر از isTraversalGroup استفاده می‌کند. چهار عنصر نوشتاری منتشر می‌کند. دو عنصر سمت چپ متعلق به یک عنصر CardBox است، درحالی‌که دو عنصر سمت راست متعلق به عنصر CardBox دیگری است:

// CardBox() function takes in top and bottom sample text.
@Composable
fun CardBox(
    topSampleText: String,
    bottomSampleText: String,
    modifier: Modifier = Modifier
) {
    Box(modifier) {
        Column {
            Text(topSampleText)
            Text(bottomSampleText)
        }
    }
}

@Composable
fun TraversalGroupDemo() {
    val topSampleText1 = "This sentence is in "
    val bottomSampleText1 = "the left column."
    val topSampleText2 = "This sentence is "
    val bottomSampleText2 = "on the right."
    Row {
        CardBox(
            topSampleText1,
            bottomSampleText1
        )
        CardBox(
            topSampleText2,
            bottomSampleText2
        )
    }
}

کد بروندادی مشابه با برونداد زیر تولید می‌کند:

چیدمان با دو ستون متن، با ستون سمت چپ که می‌خواند «این
  جمله در ستون سمت چپ است» و ستون سمت راست که می‌خواند «این جمله در سمت راست است».
شکل ۱. چیدمانی با دو جمله (یکی در ستون سمت چپ و دیگری در ستون سمت راست).

ازآنجایی‌که هیچ معناشناسی‌ای تنظیم نشده است، رفتار پیش‌فرض صفحه‌خوان این است که عناصر را از چپ به راست و از بالا به پایین پیمایش کند. به‌دلیل این پیش‌فرض، TalkBack پاره‌جمله‌ها را به ترتیب اشتباه می‌خواند:

«این جمله در» → «این جمله در» → «ستون سمت راست است.» → «در سمت راست.»

برای اینکه تکه‌کدها به‌درستی مرتب شوند، تکه‌کد اصلی را تغییر دهید تا isTraversalGroup را روی true تنظیم کنید:

@Composable
fun TraversalGroupDemo2() {
    val topSampleText1 = "This sentence is in "
    val bottomSampleText1 = "the left column."
    val topSampleText2 = "This sentence is"
    val bottomSampleText2 = "on the right."
    Row {
        CardBox(
//      1,
            topSampleText1,
            bottomSampleText1,
            Modifier.semantics { isTraversalGroup = true }
        )
        CardBox(
//      2,
            topSampleText2,
            bottomSampleText2,
            Modifier.semantics { isTraversalGroup = true }
        )
    }
}

ازآنجایی‌که isTraversalGroup به‌طور خاص روی هر CardBox تنظیم شده است، مرزهای CardBox هنگام مرتب کردن عناصر آن اعمال می‌شود. در این مورد، ابتدا CardBox سمت راست و سپس CardBox سمت چپ خوانده می‌شود.

اکنون TalkBack تکه‌های جمله را به ترتیب درست می‌خواند:

«این جمله در» → «ستون سمت راست است.» → «این جمله» → «در سمت راست است.»

سفارشی‌سازی ترتیب پیمایش

traversalIndex یک ویژگی شناور است که به شما امکان می‌دهد ترتیب پیمایش TalkBack را سفارشی‌سازی کنید. اگر گروه‌بندی عناصر با هم برای عملکرد صحیح TalkBack کافی نیست، از traversalIndex همراه با isTraversalGroup برای سفارشی‌سازی بیشتر ترتیب صفحه‌خوان استفاده کنید.

دارایی traversalIndex ویژگی‌های زیر را دارد:

  • عنصرهایی با مقادیر traversalIndex پایین‌تر در اولویت قرار می‌گیرند.
  • می‌تواند مثبت یا منفی باشد.
  • مقدار پیش‌فرض 0f است.
  • برای اینکه شاخص پیمایش بر رفتار پیمایش تأثیر بگذارد، باید روی عنصری تنظیم شود که خدمات دسترس‌پذیری آن را قابل‌انتخاب و قابل‌تمرکز کند، مثل عناصر روی صفحه مانند نوشتار یا دکمه‌ها.
    • تنظیم فقط traversalIndex در، برای مثال، Column تأثیری نخواهد داشت، مگراینکه isTraversalGroup نیز در ستون تنظیم شده باشد.

مثال زیر نشان می‌دهد که چگونه می‌توانید از traversalIndex و isTraversalGroup با هم استفاده کنید.

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

صفحه ساعتی که انتخابگر زمان در بالای آن قرار دارد.
شکل ۲. تصویر صفحه ساعت.

در گزیده ساده‌شده زیر، یک CircularLayout وجود دارد که در آن ۱۲ عدد از ۱۲ شروع می‌شود و به‌صورت ساعت‌گرد در دایره حرکت می‌کند:

@Composable
fun ClockFaceDemo() {
    CircularLayout {
        repeat(12) { hour ->
            ClockText(hour)
        }
    }
}

@Composable
private fun ClockText(value: Int) {
    Box(modifier = Modifier) {
        Text((if (value == 0) 12 else value).toString())
    }
}

چون صفحه ساعت با ترتیب منطقی چپ به راست و بالا به پایین پیش‌فرض خوانده نمی‌شود، TalkBack اعداد را به‌ترتیب نمی‌خواند. برای اصلاح این مشکل، از مقدار شمارنده افزایشی، همان‌طور که در گزیده زیر نشان داده شده است، استفاده کنید:

@Composable
fun ClockFaceDemo() {
    CircularLayout(Modifier.semantics { isTraversalGroup = true }) {
        repeat(12) { hour ->
            ClockText(hour)
        }
    }
}

@Composable
private fun ClockText(value: Int) {
    Box(modifier = Modifier.semantics { this.traversalIndex = value.toFloat() }) {
        Text((if (value == 0) 12 else value).toString())
    }
}

برای تنظیم صحیح ترتیب پیمایش، ابتدا CircularLayout را به گروه پیمایش تبدیل کنید و isTraversalGroup = true را تنظیم کنید. سپس، با کشیده شدن هر نوشتار ساعت روی چیدمان، traversalIndex مربوط به آن را روی مقدار شمارنده تنظیم کنید.

ازآنجایی‌که مقدار شمارنده به‌طور مداوم افزایش می‌یابد، با اضافه شدن اعداد به صفحه، مقدار هر ساعت traversalIndex بزرگ‌تر می‌شود—مقدار ساعت ۰ traversalIndex برابر با ۰ است و مقدار ساعت ۱ traversalIndex برابر با ۱ است. به این ترتیب، ترتیبی که TalkBack آن‌ها را می‌خواند تنظیم می‌شود. اکنون، اعداد داخل CircularLayout به ترتیب موردانتظار خوانده می‌شوند.

چون traversalIndexes که تنظیم شده است فقط نسبت به شاخص‌های دیگر در همان گروه‌بندی است، ترتیب بقیه صفحه حفظ شده است. به‌عبارت دیگر، تغییرات معنایی نشان‌داده‌شده در گزیده کد قبلی فقط ترتیب را در صفحه ساعتی که isTraversalGroup = true تنظیم شده است تغییر می‌دهد.

توجه داشته باشید که بدون تنظیم معناشناسی CircularLayout's روی isTraversalGroup = true، تغییرات traversalIndex همچنان اعمال می‌شود. اما بدون CircularLayout برای پیوند دادن آن‌ها، دوازده رقم صفحه ساعت در آخر، پس‌از بازدید از همه عناصر دیگر در صفحه، خوانده می‌شود. این اتفاق می‌افتد زیرا همه عناصر دیگر traversalIndex پیش‌فرض 0f دارند و عناصر نوشتاری ساعت بعداز همه عناصر 0f خوانده می‌شوند.

ملاحظات میانای برنامه‌سازی کاربردی

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

  • ‫isTraversalGroup = true باید روی والد حاوی عناصر گروه‌بندی‌شده تنظیم شود.
  • traversalIndex باید روی عنصر فرزندی تنظیم شود که معناشناسی دارد و توسط خدمات دسترس‌پذیری انتخاب خواهد شد.
  • مطمئن شوید که همه عناصری که بررسی می‌کنید در zIndex سطح یکسانی باشند، زیرا این امر بر معناشناسی و ترتیب پیمایش نیز تأثیر می‌گذارد.
  • مطمئن شوید که هیچ معناشناسی‌ای به‌طور غیرضروری ادغام نشده باشد، زیرا این امر ممکن است بر اینکه شاخص‌های پیمایش مؤلفه‌ها به کدام یک اعمال می‌شوند تأثیر بگذارد.