অ্যাক্সেসিবিলিটি পরিষেবা স্ক্রিনের এলিমেন্টগুলির মধ্যে নেভিগেট করার সময়, এই এলিমেন্টগুলি সঠিক গ্র্যানুলারিটিতে গ্রুপ করা, আলাদা করা বা এমনকি লুকানো গুরুত্বপূর্ণ। আপনার স্ক্রিনে প্রতিটি লো-লেভেল কম্পোজেবল স্বাধীনভাবে হাইলাইট করা হলে, স্ক্রিন জুড়ে সরানোর জন্য ব্যবহারকারীদের অনেক ইন্টার্যাক্ট করতে হয়। এলিমেন্টগুলি খুব বেশি আগ্রাসীভাবে একসাথে মার্জ করা হলে, ব্যবহারকারীরা বুঝতে নাও পারেন কোন এলিমেন্টগুলি যৌক্তিকভাবে একসাথে থাকে। স্ক্রিনে যদি এমন কোনও এলিমেন্ট থাকে যা শুধুমাত্র সাজানোর জন্য ব্যবহার করা হয়েছে, তাহলে সেগুলি অ্যাক্সেসিবিলিটি পরিষেবা থেকে লুকানো যেতে পারে। এইসব ক্ষেত্রে, আপনি সিম্যান্টিকস মার্জ, মুছে ফেলা এবং লুকানোর জন্য Compose API ব্যবহার করতে পারেন।
সেম্যান্টিক্স মার্জ করুন
আপনি কোনও পেরেন্ট কম্পোজেবলে clickable মডিফায়ার প্রয়োগ করলে, Compose
অটোমেটিক এর অধীনে থাকা সব চিলড্রেন এলিমেন্ট মার্জ করে দেয়। ইন্টার্যাক্টিভ Compose Material এবং Foundation কম্পোনেন্ট কীভাবে
ডিফল্ট হিসেবে মার্জিং স্ট্র্যাটেজি ব্যবহার করে তা বুঝতে,
ইন্টার্যাক্টিভ এলিমেন্ট বিভাগ দেখুন।
একটি কম্পোনেন্টে একাধিক কম্পোজেবল থাকা সাধারণ ব্যাপার। এইসব কম্পোজেবল একটি লজিক্যাল গ্রুপ তৈরি করতে পারে এবং প্রতিটিতে গুরুত্বপূর্ণ তথ্য থাকতে পারে, তবে আপনি এখনও অ্যাক্সেসিবিলিটি পরিষেবাগুলিকে একটি এলিমেন্ট হিসেবে দেখতে চাইতে পারেন।
যেমন, এমন একটি কম্পোজেবল সম্পর্কে ভাবুন যা ব্যবহারকারীর অবতার, নাম এবং কিছু অতিরিক্ত তথ্য দেখায়:
আপনি সিম্যান্টিক্স মডিফায়ারে mergeDescendants
প্যারামিটার ব্যবহার করে এইসব এলিমেন্ট মার্জ করার জন্য Compose চালু করতে পারবেন। এইভাবে, অ্যাক্সেসিবিলিটি পরিষেবা কম্পোনেন্টকে একটি এন্টিটি হিসেবে বিবেচনা করে এবং ডিসেন্ডেন্টের সব সিম্যান্টিক প্রপার্টি মার্জ করা হয়:
@Composable private fun PostMetadata(metadata: Metadata) { // Merge elements below for accessibility purposes Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Image( imageVector = Icons.Filled.AccountCircle, contentDescription = null // decorative ) Column { Text(metadata.author.name) Text("${metadata.date} • ${metadata.readTimeMinutes} min read") } } }
অ্যাক্সেসিবিলিটি পরিষেবা এখন একবারে পুরো কন্টেনারে ফোকাস করে এবং এর কন্টেন্ট মার্জ করে:
প্রতিটি সিম্যান্টিক্স প্রপার্টির একটি নির্দিষ্ট মার্জিং স্ট্র্যাটেজি আছে। যেমন,
ContentDescription প্রপার্টি সব ডিসেন্ডেন্ট ContentDescription ভ্যালু
একটি তালিকায় যোগ করে। আপনি SemanticsProperties.kt-এ mergePolicy ইমপ্লিমেন্টেশন চেক করে
সিম্যান্টিক্স প্রপার্টির মার্জিং স্ট্র্যাটেজি চেক করতে পারবেন।
প্রপার্টি পেরেন্ট বা চাইল্ড ভ্যালু নিতে পারে, ভ্যালুগুলিকে একটি তালিকা বা স্ট্রিংয়ে মার্জ করতে পারে,
একেবারেই মার্জ করার অনুমতি দেয় না এবং পরিবর্তে একটি ব্যতিক্রম বা অন্য কোনও কাস্টম মার্জিং স্ট্র্যাটেজি
প্রদর্শন করে।
অন্যান্য পরিস্থিতিও আছে যেখানে আপনি আশা করেন যে চাইল্ড সিম্যান্টিকস পেরেন্ট সিম্যান্টিকসের সাথে মার্জ হয়ে যাবে, কিন্তু তা হয় না। নিম্নলিখিত উদাহরণে, আমাদের কাছে
clickableটি চাইল্ড এলিমেন্ট সহ পেরেন্ট লিস্ট আইটেম আছে এবং আমরা আশা করতে পারি যে
পেরেন্ট সেগুলি সব মার্জ করে দেবে:
@Composable private fun ArticleListItem( openArticle: () -> Unit, addToBookmarks: () -> Unit, ) { Row(modifier = Modifier.clickable { openArticle() }) { // Merges with parent clickable: Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Article thumbnail" ) ArticleDetails() // Defies the merge due to its own clickable: BookmarkButton(onClick = addToBookmarks) } }
ব্যবহারকারী clickable আইটেম Row প্রেস করলে, এটি নিবন্ধটি খোলে। এর মধ্যে
নেস্ট করা আছে, নিবন্ধটি বুকমার্ক করার জন্য একটি BookmarkButton আছে। এই নেস্টেড বোতাম
আনমার্জ করা হিসেবে দেখানো হয়, যখন সারির মধ্যে থাকা বাকি চাইল্ড কন্টেন্ট
মার্জ করা থাকে:
Row নোডের মধ্যে একটি তালিকায় একাধিক টেক্সট রয়েছে। আনমার্জ করা ট্রিতে প্রতিটি Text কম্পোজেবলের জন্য আলাদা নোড থাকে।ডিজাইন অনুযায়ী, কিছু কম্পোজেবল অটোমেটিক কোনও পেরেন্টের অধীনে মার্জ করা হয় না। চাইল্ড
মার্জ করার সময় পেরেন্ট চাইল্ড মার্জ করতে পারে না, সেটি
সেটিং mergeDescendants = true থেকে স্পষ্টভাবে বা মার্জ হওয়া কম্পোনেন্ট
যেমন বোতাম বা ক্লিকযোগ্য আইটেম থেকে করা যায় না। নির্দিষ্ট API কীভাবে মার্জ করে বা
মার্জ করাকে অগ্রাহ্য করে তা জানা থাকলে, আপনি কিছু সম্ভাব্য অযাচিত আচরণ ডিবাগ করতে পারবেন।
চিলড্রেন এলিমেন্ট তার প্যারেন্টের অধীনে একটি লজিক্যাল এবং বোধগম্য গ্রুপ গঠন করলে
মার্জিং ব্যবহার করুন। তবে, নেস্ট করা চাইল্ডের নিজস্ব সিম্যান্টিক ম্যানুয়ালি অ্যাডজাস্ট বা সরিয়ে দেওয়ার প্রয়োজন হলে,
অন্য API আপনার প্রয়োজন আরও ভালোভাবে পূরণ করতে পারে (যেমন,
clearAndSetSemantics)।
সেম্যানটিকস মুছে দিন এবং সেট করুন
সিম্যান্টিক তথ্য সম্পূর্ণভাবে মুছে ফেলতে বা ওভাররাইট করতে হলে,
clearAndSetSemantics হল ব্যবহার করার মতো একটি শক্তিশালী API।
কোনও কম্পোনেন্টের নিজের এবং তার ডিসেন্ডেন্ট সিম্যান্টিক্স মুছে ফেলার প্রয়োজন হলে, খালি ল্যাম্বডা সহ এই API ব্যবহার করুন। When its semantics must be overwritten, include your new content inside the lambda.
মনে রাখবেন যে খালি ল্যাম্বডা দিয়ে মুছে দেওয়ার সময়, মুছে দেওয়া সিম্যান্টিক্স
অ্যাক্সেসিবিলিটি, অটোফিল বা টেস্টিংয়ের মতো এই তথ্য ব্যবহার করে এমন কোনও গ্রাহকের কাছে
পাঠানো হয় না। clearAndSetSemantics{/*semantic information*/}-এর মাধ্যমে কন্টেন্ট ওভাররাইট করার সময়, নতুন সিম্যান্টিক্স এলিমেন্ট ও তার ডিসেন্ডেন্টের আগের সব সিম্যান্টিক্স রিপ্লেস করে দেয়।
নিচে কাস্টম টগল কম্পোনেন্টের উদাহরণ দেওয়া হল, যা আইকন ও টেক্সট সহ ইন্টার্যাক্ট করা যায় এমন সারি হিসেবে দেখানো হয়েছে:
// Developer might intend this to be a toggleable. // Using `clearAndSetSemantics`, on the Row, a clickable modifier is applied, // a custom description is set, and a Role is applied. @Composable fun FavoriteToggle() { val checked = remember { mutableStateOf(true) } Row( modifier = Modifier .toggleable( value = checked.value, onValueChange = { checked.value = it } ) .clearAndSetSemantics { stateDescription = if (checked.value) "Favorited" else "Not favorited" toggleableState = ToggleableState(checked.value) role = Role.Switch }, ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null // not needed here ) Text("Favorite?") } }
আইকন ও টেক্সটে কিছু সেম্যান্টিক তথ্য থাকলেও, একসাথে সেগুলি এই কম্পোনেন্ট টগল করা যায় বলে ইঙ্গিত করে না। মার্জ করা যথেষ্ট নয় কারণ আপনাকে কম্পোনেন্ট সম্পর্কে অতিরিক্ত তথ্য দিতে হবে।
যেহেতু উপরের স্নিপেটটি একটি কাস্টম টগল কম্পোনেন্ট তৈরি করে, তাই আপনাকে টগল করার ক্ষমতা,
সেইসাথে stateDescription,
toggleableState এবং role শব্দার্থবিদ্যা যোগ করতে হবে। এইভাবে, কম্পোনেন্টের স্ট্যাটাস ও সংশ্লিষ্ট অ্যাকশন উপলভ্য হয়—যেমন, টকব্যাক "চালু করতে ডবল ট্যাপ করুন" বলার পরিবর্তে "টগল করতে ডবল ট্যাপ করুন" বলে।
আসল সিম্যান্টিক্স মুছে দিয়ে নতুন ও আরও বর্ণনামূলক সিম্যান্টিক্স সেট করার মাধ্যমে, অ্যাক্সেসিবিলিটি পরিষেবা এখন দেখতে পাবে যে এটি একটি টগল করা যায় এমন কম্পোনেন্ট যা স্টেট পরিবর্তন করতে পারে।
clearAndSetSemantics ব্যবহার করার সময়, নিম্নলিখিত বিষয়গুলি বিবেচনা করুন:
- এই API সেট করা থাকলে পরিষেবাগুলি কোনও তথ্য পায় না, তাই এটি কম ব্যবহার করাই
ভালো।
- স্ক্রিন বোঝার জন্য AI এজেন্ট এবং একই ধরনের পরিষেবা সম্ভাব্যভাবে শব্দার্থবিদ্যা সংক্রান্ত তথ্য ব্যবহার করতে পারে এবং তাই প্রয়োজন হলেই শুধু এটি মুছে ফেলা উচিত।
- API ল্যাম্বডার মধ্যে কাস্টম সিম্যান্টিক সেট করা হতে পারে।
- মডিফায়ারের ক্রম গুরুত্বপূর্ণ―এই API যেখানে প্রয়োগ করা হয়েছে তার পরে থাকা সব সিম্যান্টিক মুছে দেয়, অন্যান্য মার্জিং স্ট্র্যাটেজি যাই হোক না কেন।
সিম্যান্টিক্স লুকান
কিছু ক্ষেত্রে, অ্যাক্সেসিবিলিটি পরিষেবায় এলিমেন্ট পাঠানোর প্রয়োজন হয় না—হতে পারে,
অ্যাক্সেসিবিলিটির জন্য সেগুলির অতিরিক্ত তথ্য অপ্রয়োজনীয় অথবা এটি সম্পূর্ণ ভিজ্যুয়াল ডেকোরেটিভ এবং নন-ইন্টার্যাক্টিভ। এইসব ক্ষেত্রে, আপনি
hideFromAccessibility API-এর মাধ্যমে এলিমেন্ট লুকাতে পারবেন।
নিম্নলিখিত উদাহরণে এমন কম্পোনেন্ট দেখানো হয়েছে যা লুকানোর প্রয়োজন হতে পারে: কম্পোনেন্ট জুড়ে থাকা অপ্রয়োজনীয় ওয়াটারমার্ক এবং তথ্যকে আলঙ্কারিকভাবে আলাদা করার জন্য ব্যবহৃত অক্ষর।
@Composable fun WatermarkExample( watermarkText: String, content: @Composable () -> Unit, ) { Box { WatermarkedContent() // Mark the watermark as hidden to accessibility services. WatermarkText( text = watermarkText, color = Color.Gray.copy(alpha = 0.5f), modifier = Modifier .align(Alignment.BottomEnd) .semantics { hideFromAccessibility() } ) } } @Composable fun DecorativeExample() { Text( modifier = Modifier.semantics { hideFromAccessibility() }, text = "A dot character that is used to decoratively separate information, like •" ) }
এখানে hideFromAccessibility ব্যবহার করলে, অ্যাক্সেসিবিলিটি পরিষেবা থেকে ওয়াটারমার্ক ও ডেকোরেশন
লুকিয়ে রাখা হয়, তবে টেস্টিংয়ের মতো অন্যান্য ব্যবহারের ক্ষেত্রে
সেগুলির সিম্যান্টিক বজায় থাকে।
ব্যবহারের ক্ষেত্রের ব্রেকডাউন
আগের API-এর মধ্যে কীভাবে স্পষ্টভাবে পার্থক্য করা যায় তা বোঝার জন্য ব্যবহারের ক্ষেত্রের একটি সারসংক্ষেপ নিচে দেওয়া হল:
- যখন কন্টেন্ট অ্যাক্সেসিবিলিটি পরিষেবার মাধ্যমে ব্যবহার করার জন্য তৈরি করা হয় না:
- কন্টেন্ট সম্ভবত আলঙ্কারিক বা অপ্রয়োজনীয় হলেও, সেটি পরীক্ষা করে দেখতেই হবে, এমন ক্ষেত্রে
hideFromAccessibilityব্যবহার করুন। - সব পরিষেবার জন্য পেরেন্ট ও চাইল্ড সিম্যান্টিকস মুছে দিতে হলে, খালি ল্যাম্বডা সহ
clearAndSetSemantics{}ব্যবহার করুন। - কোনও কম্পোনেন্টের সিম্যান্টিক্স ম্যানুয়ালি সেট করতে হলে, ল্যাম্বডার মধ্যে কন্টেন্টের সাথে
clearAndSetSemantics{/*content*/}ব্যবহার করুন।
- কন্টেন্ট সম্ভবত আলঙ্কারিক বা অপ্রয়োজনীয় হলেও, সেটি পরীক্ষা করে দেখতেই হবে, এমন ক্ষেত্রে
- কন্টেন্টকে যখন একটি এন্টিটি হিসেবে বিবেচনা করা উচিত এবং সম্পূর্ণ করার জন্য এর সব চাইল্ডের তথ্য প্রয়োজন:
- মার্জ সিম্যান্টিক ডিসেন্ডেন্ট ব্যবহার করুন।
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- Compose-এ অ্যাক্সেসিবিলিটি
- [Material Design 2 in Compose][19]
- আপনার Compose লেআউট টেস্ট করা