پیش فرض های API

APIهای Material، Compose UI و Foundation به طور پیش‌فرض بسیاری از شیوه‌های قابل دسترس را پیاده‌سازی و ارائه می‌کنند. آنها حاوی معنایی داخلی هستند که از نقش و عملکرد خاص آنها پیروی می کنند، به این معنی که اکثر پشتیبانی های دسترسی با کار اضافی کم یا بدون کار اضافی ارائه می شود.

استفاده از APIهای مناسب برای هدف مناسب معمولاً به این معنی است که مؤلفه‌ها دارای رفتارهای دسترسی از پیش تعریف‌شده هستند که موارد استفاده استاندارد را پوشش می‌دهند، اما به یاد داشته باشید که دوبار بررسی کنید که آیا این پیش‌فرض‌ها با نیازهای دسترسی شما مطابقت دارند یا خیر. در غیر این صورت، Compose همچنین راه هایی برای پوشش نیازمندی های خاص تر ارائه می دهد.

دانستن معانی و الگوهای دسترسی پیش‌فرض در Compose API به درک نحوه استفاده از آنها با در نظر گرفتن قابلیت دسترسی و همچنین پشتیبانی از دسترسی در مؤلفه‌های سفارشی‌تر کمک می‌کند.

حداقل اندازه های هدف لمسی

هر عنصر روی صفحه‌ای که کسی می‌تواند روی آن کلیک کند، لمس کند یا با آن تعامل داشته باشد باید به اندازه کافی بزرگ باشد تا تعامل قابل اعتمادی داشته باشد. هنگام اندازه‌گیری این عناصر، مطمئن شوید که حداقل اندازه را روی 48dp تنظیم کنید تا به درستی از دستورالعمل‌های دسترسی طراحی مواد پیروی کنید.

اجزای متریال - مانند Checkbox ، RadioButton ، Switch ، Slider و Surface - این حداقل اندازه را به صورت داخلی تنظیم می‌کنند، اما فقط زمانی که مؤلفه بتواند اقدامات کاربر را دریافت کند. به عنوان مثال، هنگامی که یک Checkbox پارامتر onCheckedChange خود را روی یک مقدار غیر تهی تنظیم می کند، چک باکس شامل padding می شود که عرض و ارتفاع حداقل 48 dp داشته باشد.

@Composable
private fun CheckableCheckbox() {
    Checkbox(checked = true, onCheckedChange = {})
}

یک چک باکس با بالشتک پیش‌فرض با عرض و ارتفاع 48 dp.
شکل 1. یک چک باکس با بالشتک پیش فرض.

هنگامی که پارامتر onCheckedChange روی null تنظیم می شود، padding شامل نمی شود، زیرا نمی توان مستقیماً با مؤلفه تعامل کرد.

@Composable
private fun NonClickableCheckbox() {
    Checkbox(checked = true, onCheckedChange = null)
}

چک باکسی که هیچ بالشتکی ندارد.
شکل 2. یک چک باکس بدون بالشتک.

هنگام اجرای کنترل‌های انتخاب مانند Switch ، RadioButton ، یا Checkbox ، معمولاً رفتار قابل کلیک را با تنظیم کردن تماس برگشتی کلیک روی composable روی null ، و افزودن یک اصلاح‌کننده toggleable یا selectable به Composable والد، برمی‌دارید.

@Composable
private fun CheckableRow() {
    MaterialTheme {
        var checked by remember { mutableStateOf(false) }
        Row(
            Modifier
                .toggleable(
                    value = checked,
                    role = Role.Checkbox,
                    onValueChange = { checked = !checked }
                )
                .padding(16.dp)
                .fillMaxWidth()
        ) {
            Text("Option", Modifier.weight(1f))
            Checkbox(checked = checked, onCheckedChange = null)
        }
    }
}

یک کادر انتخاب در کنار متن «گزینه» که در حال انتخاب و لغو انتخاب است.
شکل 3. یک چک باکس با رفتار قابل کلیک.

هنگامی که اندازه یک ترکیب قابل کلیک کوچکتر از حداقل اندازه هدف لمسی باشد، Compose همچنان اندازه هدف لمسی را افزایش می دهد. این کار را با گسترش اندازه هدف لمسی در خارج از مرزهای قابل ترکیب انجام می دهد.

مثال زیر حاوی یک Box بسیار کوچک قابل کلیک است. ناحیه هدف لمسی به طور خودکار فراتر از مرزهای Box گسترش می‌یابد، بنابراین ضربه زدن در کنار Box همچنان رویداد کلیک را آغاز می‌کند.

@Composable
private fun SmallBox() {
    var clicked by remember { mutableStateOf(false) }
    Box(
        Modifier
            .size(100.dp)
            .background(if (clicked) Color.DarkGray else Color.LightGray)
    ) {
        Box(
            Modifier
                .align(Alignment.Center)
                .clickable { clicked = !clicked }
                .background(Color.Black)
                .size(1.dp)
        )
    }
}

یک کادر بسیار کوچک قابل کلیک که با ضربه زدن در کنار جعبه به یک هدف لمسی بزرگتر گسترش می یابد.
شکل 4. یک جعبه بسیار کوچک قابل کلیک که به یک هدف لمسی بزرگتر گسترش یافته است.

برای جلوگیری از همپوشانی احتمالی بین نواحی لمسی مواد ترکیب‌پذیر مختلف، همیشه از حداقل اندازه کافی بزرگ برای ترکیب‌سازی استفاده کنید. در مثال، این به معنای استفاده از تغییر دهنده sizeIn برای تنظیم حداقل اندازه برای جعبه داخلی است:

@Composable
private fun LargeBox() {
    var clicked by remember { mutableStateOf(false) }
    Box(
        Modifier
            .size(100.dp)
            .background(if (clicked) Color.DarkGray else Color.LightGray)
    ) {
        Box(
            Modifier
                .align(Alignment.Center)
                .clickable { clicked = !clicked }
                .background(Color.Black)
                .sizeIn(minWidth = 48.dp, minHeight = 48.dp)
        )
    }
}

جعبه بسیار کوچک از مثال قبلی برای ایجاد یک هدف لمسی بزرگتر اندازه آن افزایش یافته است.
شکل 5. یک جعبه بزرگتر هدف لمسی.

عناصر گرافیکی

وقتی یک Image یا Icon قابل ترکیب تعریف می‌کنید، هیچ راه خودکاری برای چارچوب Android برای درک آنچه برنامه نمایش می‌دهد وجود ندارد. شما باید یک توضیح متنی از عنصر گرافیکی را ارسال کنید.

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

نواری از چهار نماد قابل کلیک، با نماد اشتراک گذاری برجسته.
شکل 6. ردیفی از نمادهای قابل کلیک با نماد اشتراک گذاری انتخاب شده است.

بر اساس آیکون به تنهایی، چارچوب اندروید نمی تواند آن را برای یک کاربر کم بینا توصیف کند. فریم ورک اندروید نیاز به توضیح متنی اضافی از نماد دارد.

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

@Composable
private fun ShareButton(onClick: () -> Unit) {
    IconButton(onClick = onClick) {
        Icon(
            imageVector = Icons.Filled.Share,
            contentDescription = stringResource(R.string.label_share)
        )
    }
}

برخی از عناصر گرافیکی صرفاً تزئینی هستند و ممکن است نخواهید آنها را به کاربر منتقل کنید. هنگامی که پارامتر contentDescription را روی null تنظیم می کنید، به چارچوب Android نشان می دهید که این عنصر عملکرد یا وضعیت مرتبطی ندارد.

@Composable
private fun PostImage(post: Post, modifier: Modifier = Modifier) {
    val image = post.imageThumb ?: painterResource(R.drawable.placeholder_1_1)

    Image(
        painter = image,
        // Specify that this image has no semantic meaning
        contentDescription = null,
        modifier = modifier
            .size(40.dp, 40.dp)
            .clip(MaterialTheme.shapes.small)
    )
}

contentDescription عمدتاً برای عناصر گرافیکی مانند تصاویر استفاده می شود. مؤلفه‌های مادی، مانند Button یا Text ، و رفتارهای عملی، مانند clickable یا toggleable ، همراه با معنایی از پیش تعریف‌شده دیگری هستند که رفتار ذاتی آنها را توصیف می‌کنند و می‌توانند از طریق سایر APIهای Compose تغییر داده شوند.

عناصر تعاملی

APIهای Material and Foundation Compose عناصر رابط کاربری را می سازند که کاربران می توانند از طریق APIهای اصلاح کننده clickable و toggleable با آنها تعامل داشته باشند. از آنجایی که مولفه‌های قابل تعامل ممکن است از چندین عنصر تشکیل شده باشند، clickable و toggleable به طور پیش‌فرض معنای فرزندان خود را ادغام می‌کنند، به طوری که مؤلفه به عنوان یک موجودیت منطقی در نظر گرفته می‌شود.

به عنوان مثال، یک Button مواد ممکن است از یک نماد فرزند و مقداری متن تشکیل شده باشد. به‌جای اینکه با کودکان به‌عنوان یک فرد رفتار کند، یک دکمه Material به‌طور پیش‌فرض معنای فرزندان خود را ادغام می‌کند تا سرویس‌های دسترس‌پذیری بتوانند آنها را بر این اساس گروه‌بندی کنند:

دکمه هایی با معنای کودکان ادغام نشده در مقابل ادغام شده.
شکل 7. دکمه هایی با معنای کودکان ادغام نشده در مقابل ادغام شده.

به طور مشابه، استفاده از اصلاح‌کننده clickable همچنین باعث می‌شود که یک composable معنایی نوادگان خود را در یک موجودیت واحد ادغام کند، که با یک نمایش عمل مربوطه به سرویس‌های دسترسی ارسال می‌شود:

Row(
    // Uses `mergeDescendants = true` under the hood
    modifier = Modifier.clickable { openArticle() }
) {
    Icon(
        painter = painterResource(R.drawable.ic_logo),
        contentDescription = "Open",
    )
    Text("Accessibility in Compose")
}

همچنین می‌توانید یک onClickLabel خاص را روی صفحه قابل کلیک والدین تنظیم کنید تا اطلاعات بیشتری را برای سرویس‌های دسترس‌پذیری ارائه کنید و نمایش دقیق‌تری از عملکرد ارائه دهید:

Row(
    modifier = Modifier
        .clickable(onClickLabel = "Open this article") {
            openArticle()
        }
) {
    Icon(
        painter = painterResource(R.drawable.ic_logo),
        contentDescription = "Open"
    )
    Text("Accessibility in Compose")
}

با استفاده از TalkBack به عنوان مثال، این اصلاح‌کننده clickable و برچسب کلیک آن TalkBack را قادر می‌سازد تا به جای بازخورد پیش‌فرض عمومی‌تر «دو ضربه برای فعال‌سازی»، اشاره‌ای به عملکرد «برای باز کردن این مقاله دو بار ضربه بزنید» ارائه دهد.

این بازخورد بسته به نوع عمل تغییر می کند. یک کلیک طولانی می‌تواند یک اشاره TalkBack از «دوبار ضربه بزنید و نگه دارید تا»، و به دنبال آن یک برچسب ارائه می‌کند:

Row(
    modifier = Modifier
        .combinedClickable(
            onLongClickLabel = "Bookmark this article",
            onLongClick = { addToBookmarks() },
            onClickLabel = "Open this article",
            onClick = { openArticle() },
        )
) {}

در برخی موارد، ممکن است دسترسی مستقیم به اصلاح کننده clickable نداشته باشید (به عنوان مثال، زمانی که در جایی در یک لایه تودرتو پایین تنظیم شده است)، اما همچنان بخواهید برچسب اعلامیه را از حالت پیش فرض تغییر دهید. برای انجام این کار، تنظیمات clickable را از اصلاح اعلان با استفاده از اصلاح کننده semantics و تنظیم برچسب کلیک در آنجا جدا کنید تا نمایش عمل را تغییر دهید:

@Composable
private fun ArticleList(openArticle: () -> Unit) {
    NestedArticleListItem(
        // Clickable is set separately, in a nested layer:
        onClickAction = openArticle,
        // Semantics are set here:
        modifier = Modifier.semantics {
            onClick(
                label = "Open this article",
                action = {
                    // Not needed here: openArticle()
                    true
                }
            )
        }
    )
}

در این حالت، نیازی نیست که عمل کلیک را دو بار انجام دهید، زیرا API های Compose موجود، مانند clickable یا Button ، این کار را برای شما انجام می دهند. این به این دلیل است که منطق ادغام تضمین می کند که خارجی ترین برچسب اصلاح کننده و اقدام برای اطلاعات موجود انجام می شود.

در مثال قبلی، اکشن کلیک openArticle() توسط NestedArticleListItem به طور خودکار به معنایی clickable آن منتقل می‌شود و می‌تواند در دومین اقدام اصلاح‌کننده معنایی خالی بماند. با این حال، برچسب کلیک از دومین اصلاح کننده معنایی onClick(label = "Open this article") گرفته شده است، زیرا در مورد اول وجود نداشت.

ممکن است با سناریوهایی مواجه شوید که در آن انتظار داشته باشید معناشناسی کودکان در یک سناریو والد ادغام شود، اما این اتفاق نمی افتد. برای اطلاعات بیشتر به ادغام و پاکسازی مراجعه کنید.

اجزای سفارشی

برای مؤلفه‌های سفارشی، به عنوان یک قاعده کلی، به اجرای یک مؤلفه مشابه در کتابخانه Material یا سایر کتابخانه‌های Compose نگاه کنید و رفتار دسترسی آن را در جایی که معقول است تقلید یا تغییر دهید.

به عنوان مثال، اگر شما در حال جایگزینی Material Checkbox با پیاده‌سازی خود هستید، مشاهده اجرای Checkbox موجود به شما یادآوری می‌کند که اصلاح‌کننده triStateToggleable را اضافه کنید، که ویژگی‌های دسترسی را برای این مؤلفه کنترل می‌کند.

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

همچنین می‌توانید نمونه‌ای از یک مؤلفه جابجایی سفارشی را در بخش Clear and set semantics و همچنین اطلاعات دقیق‌تری درباره نحوه پشتیبانی از دسترسی در مؤلفه‌های سفارشی در دستورالعمل‌های API پیدا کنید.

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}