অ্যাপ অ্যাক্সেসিবিলিটি উন্নত করার নীতি

অ্যাক্সেসিবিলিটি সংক্রান্ত প্রয়োজন আছে এমন ব্যবহারকারীদের সাহায্য করতে, Android ফ্রেমওয়ার্ক আপনাকে এমন একটি অ্যাক্সেসিবিলিটি পরিষেবা তৈরি করতে দেয় যা ব্যবহারকারীদের কাছে অ্যাপ থেকে কন্টেন্ট দেখাতে পারে এবং তাদের হয়ে অ্যাপও অপারেট করতে পারে।

Android-এ বিভিন্ন সিস্টেম অ্যাক্সেসিবিলিটি পরিষেবা উপলভ্য, যার মধ্যে নিম্নলিখিতগুলি অন্তর্ভুক্ত:

  • টকব্যাক: ক্ষীণ দৃষ্টিসম্পন্ন বা দৃষ্টিশক্তিহীন ব্যক্তিদের সাহায্য করে। এটি সিন্থেসাইজড ভয়েসের মাধ্যমে কন্টেন্ট ঘোষণা করে এবং ব্যবহারকারীর জেসচারের উত্তরে অ্যাপে অ্যাকশন পারফর্ম করে।
  • Switch Access: যাদের চলনে অক্ষমতা আছে তাদের সাহায্য করে। এটি ইন্টার‍্যাক্টিভ এলিমেন্ট হাইলাইট করে এবং ব্যবহারকারী কোনও বোতাম প্রেস করলে তার উত্তরে অ্যাকশন পারফর্ম করে। এটি শুধুমাত্র এক বা দুটি বোতাম ব্যবহার করে ডিভাইস কন্ট্রোল করার অনুমতি দেয়।

অ্যাক্সেসিবিলিটি সংক্রান্ত প্রয়োজনীয়তা আছে এমন ব্যক্তিদের আপনার অ্যাপ সফলভাবে ব্যবহার করতে সাহায্য করার জন্য, আপনার অ্যাপকে অবশ্যই এই পৃষ্ঠায় বর্ণনা করা পেশাদার পদ্ধতি অনুসরণ করতে হবে, যা অ্যাপ আরও অ্যাক্সেসযোগ্য করে তুলুন-এ বর্ণনা করা নির্দেশিকার উপর ভিত্তি করে তৈরি করা হয়েছে।

এইসব পেশাদার পদ্ধতির প্রতিটি, যা নিম্নলিখিত বিভাগে বর্ণনা করা হয়েছে, আপনার অ্যাপের অ্যাক্সেসিবিলিটি আরও উন্নত করতে পারে:

লেবেল এলিমেন্ট
ব্যবহারকারীদের অবশ্যই আপনার অ্যাপের মধ্যে প্রতিটি ইন্টার‍্যাক্টিভ এবং অর্থপূর্ণ UI এলিমেন্টের কন্টেন্ট এবং উদ্দেশ্য বুঝতে হবে।
অ্যাক্সেসিবিলিটি অ্যাকশন যোগ করা
অ্যাক্সেসিবিলিটি অ্যাকশন যোগ করার মাধ্যমে, আপনি অ্যাক্সেসিবিলিটি পরিষেবার ব্যবহারকারীদের আপনার অ্যাপের মধ্যে গুরুত্বপূর্ণ ইউজার ফ্লো সম্পূর্ণ করার সুবিধা দিতে পারবেন।
বিল্ট-ইন অ্যাক্সেসিবিলিটি ফিচার ব্যবহার করা
Compose ডিফল্ট হিসেবে অনেক অ্যাক্সেসিবিলিটি আচরণ অফার করে। অ্যাক্সেসিবিলিটি সংক্রান্ত আগে থেকে নির্ধারিত আচরণের সুবিধা নিন যাতে অতিরিক্ত কাজ না করেই বা সামান্য কাজ করেই আপনার কম্পোনেন্ট অ্যাক্সেসযোগ্য করে তুলতে পারেন। এছাড়াও, Compose-এ এমন কিছু উপায় আছে যার মাধ্যমে ডিফল্ট ফিচারে কভার করা হয়নি এমন আরও নির্দিষ্ট অ্যাক্সেসিবিলিটি সংক্রান্ত প্রয়োজনীয়তা পূরণ করা যায়।
রঙ ছাড়া অন্য ইঙ্গিত ব্যবহার করুন
ব্যবহারকারীদের অবশ্যই UI-তে বিভিন্ন বিভাগের এলিমেন্টের মধ্যে স্পষ্টভাবে পার্থক্য করতে পারতে হবে। এটি করতে, এই পার্থক্যগুলি প্রকাশ করার জন্য রঙের পাশাপাশি প্যাটার্ন এবং অবস্থান ব্যবহার করুন।
মিডিয়া কন্টেন্ট আরও অ্যাক্সেসযোগ্য করে তোলা
আপনার অ্যাপের ভিডিও বা অডিও কন্টেন্টে বিবরণ যোগ করুন যাতে এই কন্টেন্ট ব্যবহারকারী সম্পূর্ণরূপে ভিজ্যুয়াল বা অডিও সংকেতের উপর নির্ভর না করেন।

লেবেল এলিমেন্ট

আপনার অ্যাপের প্রতিটি ইন্টার‍্যাক্টিভ UI এলিমেন্টের জন্য ব্যবহারকারীদের উপযোগী ও বর্ণনামূলক লেবেল প্রদান করা গুরুত্বপূর্ণ। প্রতিটি লেবেলকে নির্দিষ্ট এলিমেন্টের শব্দার্থ ব্যাখ্যা করতে হবে—অর্থাৎ, এলিমেন্টের অর্থ ও উদ্দেশ্য। টকব্যাকের মতো স্ক্রিন রিডার ব্যবহারকারীদের জন্য এই লেবেলগুলি ঘোষণা করতে পারে।

বেশিরভাগ ক্ষেত্রে, Compose API এবং Material-এ ডিফল্ট অ্যাক্সেসিবিলিটি সহায়তা থাকে। তবে, আপনাকে যদি ম্যানুয়ালি UI এলিমেন্টের সিম্যান্টিক প্রপার্টি নির্দিষ্ট করতে হয়, তাহলে semantics মডিফায়ার এবং contentDescription প্রপার্টি ব্যবহার করুন। সিম্যান্টিক্স সম্পর্কে আরও তথ্যের জন্য, সিম্যান্টিক্স দেখুন।

নিম্নলিখিত বিভাগে অন্যান্য লেবেলিং টেকনিকের ব্যাপারে বর্ণনা করা হয়েছে।

এডিট করা যায় এমন এলিমেন্ট

এডিট করা যায় এমন এলিমেন্টে লেবেল যোগ করার সময়, যেমন টেক্সট ফিল্ড, এমন টেক্সট দেখানো সহায়ক হয় যা এলিমেন্টের মধ্যেই সঠিক ইনপুটের উদাহরণ দেয়, এর পাশাপাশি এই উদাহরণ টেক্সট স্ক্রিন রিডারের জন্য উপলভ্য করে। এইসব পরিস্থিতিতে, আপনি প্লেসহোল্ডার টেক্সট ব্যবহার করতে পারেন, যাকে ইঙ্গিত টেক্সটও বলা হয়।

নিচের উদাহরণে, TextField-এর একটি placeholder প্যারামিটার আছে যা ইঙ্গিত টেক্সট প্রদান করে।

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

এছাড়াও, টেক্সট ফিল্ডের সাথে একটি বর্ণনামূলক লেবেল থাকা সাধারণ ব্যাপার, যা ব্যবহারকারীদের ইনপুট হিসেবে কী লিখতে হবে তা বর্ণনা করে।

নিম্নলিখিত উদাহরণে, TextField-এ label প্যারামিটার আছে যা অ্যাক্সেসিবিলিটি সংক্রান্ত বিবরণ প্রদান করে।

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

টেক্সট ও ব্যবহারকারীর ইনপুট সম্পর্কে আরও জানতে, টেক্সট ফিল্ড কনফিগার করুন দেখুন।

কালেকশনে থাকা এলিমেন্ট

কোনও কালেকশনের এলিমেন্টে লেবেল যোগ করার সময়, প্রতিটি লেবেল অনন্য হতে হবে। এইভাবে, সিস্টেমের অ্যাক্সেসিবিলিটি পরিষেবা কোনও লেবেল ঘোষণা করার সময় স্ক্রিনে ঠিক একটি এলিমেন্টকে রেফার করতে পারে। এই চিঠিপত্র ব্যবহারকারীদের জানতে দেয় যে কখন তারা UI-এর মাধ্যমে সাইকেল চালায় বা কখন তারা কোনও এলিমেন্টে ফোকাস সরায় যা তারা আগেই আবিষ্কার করেছে।

যেমন, আপনার কাছে LazyColumn বা LazyRow থাকলে, প্রতিটি আইটেমে অনন্য collectionItemInfo অ্যাসাইন করতে semantics মডিফায়ার ব্যবহার করুন, যেমনটি নিম্নলিখিত স্নিপেটে দেখানো হয়েছে:

MilkyWayList(
    modifier = Modifier
        .semantics {
            collectionInfo = CollectionInfo(
                rowCount = milkyWay.count(),
                columnCount = 1
            )
        }
) {
    milkyWay.forEachIndexed { index, text ->
        Text(
            text = text,
            modifier = Modifier.semantics {
                collectionItemInfo =
                    CollectionItemInfo(index, 0, 0, 0)
            }
        )
    }
}

তালিকা ও গ্রিডের জন্য সিম্যান্টিক প্রপার্টি সম্পর্কে আরও তথ্যের জন্য, তালিকা ও আইটেম সংক্রান্ত তথ্য দেখুন।

সম্পর্কিত কন্টেন্টের গ্রুপ

আপনার অ্যাপে যদি এমন একাধিক UI এলিমেন্ট থাকে যা একটি স্বাভাবিক গ্রুপ তৈরি করে, যেমন কোনও গানের বিবরণ বা মেসেজের অ্যাট্রিবিউট, তাহলে এইসব এলিমেন্টকে একটি পেরেন্ট কন্টেনারের (যেমন Column, Row বা Box) মধ্যে সাজান। পেরেন্ট কন্টেনারের semantics মডিফায়ার ব্যবহার করে mergeDescendants-কে true-এ সেট করুন।

এইভাবে, অ্যাক্সেসিবিলিটি পরিষেবা, একটিই ঘোষণার মাধ্যমে, ভিতরের এলিমেন্টের কন্টেন্টের বিবরণ একটির পর একটি করে দেখাতে পারে। সম্পর্কিত এলিমেন্ট একত্রিত করলে, সহায়ক টেকনোলজি ব্যবহারকারীরা স্ক্রিনে আরও দক্ষতার সাথে তথ্য খুঁজে পেতে পারেন।

নিম্নলিখিত স্নিপেটে, Row কম্পোজেবল পেরেন্ট কন্টেনার হিসেবে কাজ করে। Row-এর মধ্যে সম্পর্কিত এলিমেন্ট আছে যা ব্লগ পোস্টের মেটাডেটা দেখায়—লেখকের অবতার, লেখকের নাম এবং আনুমানিক পড়ার সময়। mergeDescendants-কে true-এ সেট করলে, এই ইনার এলিমেন্টগুলি গ্রুপ করা হয়, যাতে অ্যাক্সেসিবিলিটি পরিষেবা সেগুলিকে একটি ইউনিট হিসেবে বিবেচনা করতে পারে।

@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")
        }
    }
}

আগের উদাহরণের মতো সম্পর্কিত এলিমেন্ট গ্রুপ করার সময়, শুধুমাত্র পেরেন্ট কন্টেনারকে ইন্টার‌্যাক্টিভ করুন। ইনার চাইল্ড এলিমেন্টে clickable বা focusable মডিফায়ার যোগ করা এড়িয়ে চলুন। পরিবর্তে, মূল এলিমেন্ট Row বা Column-এ মডিফায়ার প্রয়োগ করুন।

অ্যাক্সেসিবিলিটি পরিষেবাগুলি একবারে ভিতরের এলিমেন্টের বিবরণ ঘোষণা করে, তাই এলিমেন্টের অর্থ বোঝানোর পাশাপাশি প্রতিটি বিবরণ যতটা সম্ভব ছোট রাখা গুরুত্বপূর্ণ।

মনে রাখবেন: সাধারণত, কোনও গ্রুপের জন্য কন্টেন্টের বিবরণ তৈরি করার সময়, এর চাইল্ডের টেক্সট একত্রিত করা এড়িয়ে চলুন। এটি করলে গ্রুপের বিবরণ ভঙ্গুর হয়ে যায় এবং চাইল্ডের টেক্সট পরিবর্তন হলে, গ্রুপের বিবরণ আর দৃশ্যমান টেক্সটের সাথে নাও মিলতে পারে।

তালিকা বা গ্রিড প্রসঙ্গে, স্ক্রিন রিডার তালিকা বা গ্রিড এলিমেন্টের চাইল্ড টেক্সট নোডের টেক্সট একত্রিত করতে পারে। এই ঘোষণাটি পরিবর্তন না করাই ভাল।

সিম্যান্টিক মার্জ করা সম্পর্কে আরও তথ্যের জন্য, মার্জ ও মুছে ফেলা দেখুন।

টেক্সটের মধ্যে শিরোনাম

কিছু অ্যাপ স্ক্রিনে দেখানো টেক্সটের গ্রুপের সারসংক্ষেপ করতে শিরোনাম ব্যবহার করে। কোনও নির্দিষ্ট এলিমেন্ট যদি হেডিংকে দেখায়, তাহলে আপনি semantics মডিফায়ারে heading প্রপার্টি সেট করে অ্যাক্সেসিবিলিটি পরিষেবার জন্য এর উদ্দেশ্য নির্দেশ করতে পারেন।

@Composable
private fun Subsection(text: String) {
    Text(
        text = text,
        style = MaterialTheme.typography.headlineSmall,
        modifier = Modifier.semantics { heading() }
    )
}

অ্যাক্সেসিবিলিটি পরিষেবার ব্যবহারকারীরা প্যারাগ্রাফ বা শব্দের পরিবর্তে শিরোনামের মধ্যে নেভিগেট করার বিকল্প বেছে নিতে পারেন। এই নমনীয়তা টেক্সট নেভিগেশনের অভিজ্ঞতাকে উন্নত করে।

heading সিম্যান্টিক্স প্রপার্টি সম্পর্কে আরও জানতে, শিরোনাম দেখুন।

অ্যাক্সেসিবিলিটি প্যানেলের টাইটেল

Android 9 (API লেভেল ২৮) এবং তার পরবর্তী ভার্সনে, আপনি স্ক্রিনের পেন-এর জন্য অ্যাক্সেসিবিলিটি-ফ্রেন্ডলি শীর্ষক প্রদান করতে পারবেন। অ্যাক্সেসিবিলিটির উদ্দেশ্যে, একটি প্যানেল হল একটি উইন্ডোর দৃশ্যত স্বতন্ত্র অংশ।

অ্যাক্সেসিবিলিটি পরিষেবার জন্য প্যানেলের উইন্ডোর মতো আচরণ বুঝতে, আপনার অ্যাপের প্যানেলে বর্ণনামূলক শিরোনাম দিন। প্যানেলের চেহারা বা কন্টেন্ট পরিবর্তন হলে, অ্যাক্সেসিবিলিটি পরিষেবা ব্যবহারকারীদের আরও বিস্তারিত তথ্য প্রদান করতে পারে।

ShareSheet(
    message = "Choose how to share this photo",
    modifier = Modifier
        .fillMaxWidth()
        .align(Alignment.TopCenter)
        .semantics { paneTitle = "New bottom sheet" }
)

paneTitle সিম্যান্টিক্স প্রপার্টি সম্পর্কে আরও জানতে, উইন্ডোর মতো কম্পোনেন্ট দেখুন।

সাজানোর এলিমেন্ট

আপনার UI-তে কোনও এলিমেন্ট যদি শুধুমাত্র ভিজ্যুয়াল স্পেসিং বা ভিজ্যুয়াল অ্যাপিয়ারেন্সের উদ্দেশ্যে থাকে, তাহলে এলিমেন্টে উপযুক্ত প্রপার্টি সেট করুন যাতে বোঝা যায় যে অ্যাক্সেসিবিলিটি পরিষেবা এটি উপেক্ষা করতে পারে।

Image বা Icon কম্পোজেবলের জন্য, contentDescription = null সেট করুন। অন্যান্য সম্পূর্ণ আলংকারিক এলিমেন্ট যা কোনও প্রসঙ্গ বা কার্যকারিতা প্রদান করে না, তার জন্য আপনি hideFromAccessibility ব্যবহার করতে পারেন। এই সিম্যান্টিক্স প্রপার্টি অ্যাক্সেসিবিলিটি পরিষেবাকে আইটেমটি উপেক্ষা করতে বলে।

কোনও ইন্টার‍্যাক্টিভ কম্পোজেবলে আলঙ্কারিক, নন-ইন্টার‍্যাক্টিভ চাইল্ড এলিমেন্ট থাকলে, অ্যাক্সেসিবিলিটি পরিষেবা যাতে সেগুলি ট্রাভার্স না করে তা নিশ্চিত করতে clearAndSetSemantics ব্যবহার করুন। মনে রাখবেন যে clearAndSetSemantics কোনও এলিমেন্ট ও তার চাইল্ডের ডিফল্ট সিম্যান্টিক্স সম্পূর্ণভাবে মুছে দেয়। এটি আপনাকে একটি নতুন, ইউনিফায়েড অ্যাক্সেসিবিলিটি এলিমেন্ট নির্ধারণ করতে দেয়। সাধারণত, আপনি জটিল কাস্টম কম্পোনেন্টের জন্য এই পদ্ধতি ব্যবহার করেন।

নিম্নলিখিত উদাহরণে, Icon এবং Text হল কাস্টম টগলের মধ্যে সাজানোর জন্য ব্যবহৃত চাইল্ড এলিমেন্ট। অ্যাক্সেসিবিলিটি পরিষেবা যাতে এইসব চাইল্ডকে আলাদাভাবে ট্রাভার্স করতে না পারে, তার জন্য আপনি পেরেন্ট Row-এ clearAndSetSemantics ব্যবহার করে তাদের সিম্যান্টিক্স মুছে দিতে পারেন। এটি অ্যাক্সেসিবিলিটি পরিষেবাকে বলে যে সম্পূর্ণ Row-কে ট্রাভার্স করা যায় এমন টগল হিসেবে বিবেচনা করতে:

// 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?")
    }
}

সিম্যান্টিক মুছে ফেলা সম্পর্কে আরও জানতে, সিম্যান্টিক মুছে ফেলা ও সেট করা দেখুন।

অ্যাক্সেসিবিলিটি অ্যাকশন যোগ করুন

অ্যাক্সেসিবিলিটি পরিষেবার ব্যবহারকারীরা যাতে আপনার অ্যাপে সব ইউজার ফ্লো সম্পূর্ণ করতে পারেন, সেটি নিশ্চিত করা গুরুত্বপূর্ণ।

আপনার কাস্টম কম্পোজেবলের ইন্টার‍্যাকশন যদি অ্যাপের স্ট্যাটাস এমনভাবে পরিবর্তন করে যা স্পষ্ট নয়, তাহলে Modifier.clickable বা Modifier.combinedClickable-এ onClickLabel বা onLongClickLabel-এর মতো প্যারামিটার ব্যবহার করে স্ট্যান্ডার্ড ট্যাপ অ্যাকশনের জন্য বর্ণনামূলক লেবেল প্রদান করুন।

স্ট্যান্ডার্ড ট্যাপে ম্যাপ করা যায় না এমন জটিল ইন্টার‍্যাকশনের জন্য customActions ব্যবহার করুন।

যেমন, আপনার অ্যাপ ব্যবহারকারীকে কোনও আইটেম অন্য লোকেশনে টেনে নিয়ে যেতে বা তালিকার কোনও আইটেমে সোয়াইপ করতে দিলে, আপনি অ্যাক্সেসিবিলিটি পরিষেবায় অ্যাকশনটি প্রকাশ করে এই ব্যবহারকারী ফ্লো সম্পূর্ণ করার বিকল্প উপায় প্রদান করতে পারেন। এইভাবে, TalkBack, Voice Access বা সুইচ অ্যাক্সেস ব্যবহারকারীরা এমন অ্যাকশন পারফর্ম করতে পারবেন যা অন্যথায় শুধুমাত্র জেসচারের মাধ্যমে উপলভ্য হতে পারে।

Compose-এ, আপনি semantics মডিফায়ারে customActions প্রপার্টির মাধ্যমে কাস্টম অ্যাক্সেসিবিলিটি অ্যাকশন সংজ্ঞায়িত করতে পারবেন, CustomAccessibilityAction ব্যবহার করে।

যেমন, আপনার অ্যাপে কোনও আইটেম সোয়াইপ করে বাতিল করার সুবিধা থাকলে, আপনি কাস্টম অ্যাক্সেসিবিলিটি অ্যাকশনের মাধ্যমে সেই ফাংশনালিটি দেখাতে পারেন:

SwipeToDismissBox(
    modifier = Modifier.semantics {
        // Represents the swipe to dismiss for accessibility
        customActions = listOf(
            CustomAccessibilityAction(
                label = "Remove article from list",
                action = {
                    removeArticle()
                    true
                }
            )
        )
    },
    state = rememberSwipeToDismissBoxState(),
    backgroundContent = {}
) {
    ArticleListItem()
}

কাস্টম অ্যাক্সেসিবিলিটি অ্যাকশন প্রয়োগ করা থাকলে, ব্যবহারকারীরা অ্যাকশন মেনুর মাধ্যমে অ্যাকশন অ্যাক্সেস করতে পারবেন।

কাস্টম অ্যাকশন সম্পর্কে আরও জানতে, কাস্টম অ্যাকশন দেখুন।

উপলভ্য অ্যাকশনগুলি বোধগম্য করে তুলুন

কোনও UI এলিমেন্ট টাচ করে ধরে রাখার মতো অ্যাকশন সাপোর্ট করলে, টকব্যাকের মতো অ্যাক্সেসিবিলিটি পরিষেবা সেটিকে "বেশিক্ষণ প্রেস করে রাখার জন্য ডবল ট্যাপ করে ধরে রাখুন" হিসেবে ঘোষণা করে।

এই সাধারণ ঘোষণা ব্যবহারকারীকে কোনও প্রসঙ্গ দেয় না যে টাচ করে ধরে রাখার অ্যাকশন কী করে।

এই ঘোষণা আরও উপযোগী করে তুলতে, অ্যাকশনের জন্য একটি অর্থপূর্ণ বিবরণ উল্লেখ করুন।

Compose-এ, clickable এবং combinedClickable-এর মতো স্ট্যান্ডার্ড ইন্টার‍্যাকশন মডিফায়ারে বিল্ট-ইন প্যারামিটার (যেমন onClickLabel এবং onLongClickLabel) থাকে যা আপনি অ্যাকশনের বিবরণ দিতে ব্যবহার করতে পারেন, যেমন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

var contextMenuPhotoId by rememberSaveable { mutableStateOf<Int?>(null) }
val haptics = LocalHapticFeedback.current
LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) {
    items(photos, { it.id }) { photo ->
        ImageItem(
            photo,
            Modifier
                .combinedClickable(
                    onClick = { activePhotoId = photo.id },
                    onLongClick = {
                        haptics.performHapticFeedback(HapticFeedbackType.LongPress)
                        contextMenuPhotoId = photo.id
                    },
                    onLongClickLabel = stringResource(R.string.open_context_menu)
                )
        )
    }
}
if (contextMenuPhotoId != null) {
    PhotoActionsSheet(
        photo = photos.first { it.id == contextMenuPhotoId },
        onDismissSheet = { contextMenuPhotoId = null }
    )
}

এর ফলে টকব্যাক "সংশ্লিষ্ট মেনু খুলুন" ঘোষণা করে, যা ব্যবহারকারীদের অ্যাকশনের উদ্দেশ্য বুঝতে সাহায্য করে।

এছাড়াও, আপনি সরাসরি semantics মডিফায়ারে লেবেল উল্লেখ করতে পারেন।

ট্যাপ ও ক্লিক করার ব্যাপারে আরও তথ্য পেতে, ট্যাপ ও প্রেস করুন এবং ইন্টার‍্যাক্টিভ এলিমেন্ট দেখুন।

বিল্ট-ইন অ্যাক্সেসিবিলিটি ফিচার ব্যবহার করা

আপনার অ্যাপের UI ডিজাইন করার সময়, আগে থেকে থাকা কার্যকারিতা আবার প্রয়োগ করা এড়াতে বিল্ট-ইন অ্যাক্সেসিবিলিটি ফিচারের সুবিধা নিন। Material, Compose UI, এবং Foundation API ডিফল্ট হিসেবে অনেক অ্যাক্সেসিবিলিটি সংক্রান্ত পদ্ধতি প্রয়োগ ও অফার করে।

Jetpack Compose-এ, অ্যাক্সেসযোগ্য UI তৈরি করতে Button, Switch এবং Checkbox-এর মতো বিল্ট-ইন কম্পোজেবল ব্যবহার করুন। এইসব কম্পোনেন্ট semantics মডিফায়ারের সাথে প্রি-প্যাকেজ করা থাকে, যেমন role এবং stateDescription, যা আপনি আপনার অ্যাপকে আরও অ্যাক্সেসযোগ্য করে তুলতে ব্যবহার করতে পারেন।

কাস্টম কম্পোনেন্টে সিম্যান্টিক প্রয়োগ করা

কাস্টম কম্পোনেন্ট তৈরি করার সময়, এই কম্পোনেন্টের ভূমিকা পালন করার জন্য কী ধরনের অ্যাক্সেসিবিলিটি সহায়তা প্রয়োজন তা মনে রাখবেন। সাধারণত, আপনি আগে থেকেই ব্যবহার করছেন এমন স্ট্যান্ডার্ড Compose API—যেমন clickable, toggleable বা selectable—যথেষ্ট কারণ সেগুলি আপনার জন্য সিম্যান্টিক্স ট্রি অটোমেটিক পূরণ করে।

তবে, কিছু কম্পোনেন্টের জন্য স্ট্যান্ডার্ড মডিফায়ারের চেয়ে আরও নির্দিষ্ট তথ্য প্রয়োজন। এইসব ক্ষেত্রে, বিশেষ মডিফায়ার (যেমন triStateToggleable) খুঁজুন অথবা, কোনওটি না থাকলে, লো-লেভেল Modifier.semantics ব্যবহার করে স্পষ্টভাবে সিমেন্টিক প্রদান করুন।

যেমন, একটি TriStateSwitch, তিনটি স্ট্যাটাস সহ একটি সুইচ (চালু, বন্ধ এবং অনির্দিষ্ট)।

স্ট্যান্ডার্ড toggleable মডিফায়ার দুটি স্টেট অনুমান করলেও, triStateToggleable মডিফায়ার তৃতীয় স্টেটের জটিলতা ম্যানেজ করে। এটি অটোমেটিক অ্যাক্সেসিবিলিটি Role (Switch) এবং State সেট করে। এইভাবে, অ্যাক্সেসিবিলিটি পরিষেবা সঠিক তথ্য পায় এবং আপনাকে ম্যানুয়ালি শব্দার্থবিদ্যা সংজ্ঞায়িত করতে হয় না।

নিম্নলিখিত কোড স্নিপেট এই পদ্ধতি ব্যবহার করে একটি TriStateSwitch দেখায়:

@Composable
fun TriStateSwitch(
    state: ToggleableState,
    onClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    // A real implementation would include custom drawing for the switch.
    // This example uses a Box to demonstrate the semantics.
    Box(
        modifier = modifier
            .size(width = 64.dp, height = 40.dp)
            // triStateToggleable handles the semantics (Role and State)
            // automatically, so explicit Modifier.semantics is not needed here.
            .triStateToggleable(
                state = state,
                onClick = onClick,
                role = Role.Switch
            )
            // Add visual feedback based on the state
            .background(
                when (state) {
                    ToggleableState.On -> Color.Green
                    ToggleableState.Off -> Color.Gray
                    ToggleableState.Indeterminate -> Color.Yellow
                }
            )
    )
}

// Usage within another composable:
var state by remember { mutableStateOf(ToggleableState.Off) }
TriStateSwitch(
    state = state,
    onClick = {
        state = when (state) {
            ToggleableState.Off -> ToggleableState.Indeterminate
            ToggleableState.Indeterminate -> ToggleableState.On
            ToggleableState.On -> ToggleableState.Off
        }
    }
)

কাস্টম কম্পোনেন্ট তৈরি করার সময়, অ্যাক্সেসিবিলিটির জন্য সব প্রাসঙ্গিক সিম্যান্টিক প্রপার্টি প্রদান করেছেন কিনা তা নিশ্চিত করুন। যেমন, আপনার কম্পোনেন্ট যদি সুইচ বা বোতামের মতো কোনও স্ট্যান্ডার্ড কন্ট্রোলকে নকল করে, তাহলে এই প্রপার্টিগুলির মধ্যে কম্পোনেন্টের ভূমিকা (যেমন Role.Switch বা Role.Button), stateDescription (যেমন "চালু", "বন্ধ", "চেক করা" বা "চেক না করা") এবং যেকোনও প্রাসঙ্গিক অ্যাকশন লেবেল অন্তর্ভুক্ত থাকে। আরও তথ্যের জন্য, কাস্টম কম্পোনেন্ট দেখুন।

রঙ ছাড়া অন্য ইঙ্গিত ব্যবহার করুন

বর্ণান্ধতার সমস্যা আছে এমন ব্যবহারকারীদের সাহায্য করতে, আপনার অ্যাপের স্ক্রিনে UI এলিমেন্ট আলাদা করে দেখাতে রঙের পরিবর্তে অন্য কোনও ইঙ্গিত ব্যবহার করুন। এইসব কৌশলের মধ্যে বিভিন্ন আকার বা সাইজ ব্যবহার করা, টেক্সট বা ভিজ্যুয়াল প্যাটার্ন প্রদান করা, অথবা এলিমেন্টের পার্থক্য চিহ্নিত করার জন্য অডিও- বা টাচ-ভিত্তিক (হ্যাপটিক) ফিডব্যাক যোগ করা অন্তর্ভুক্ত হতে পারে।

ছবি ১-এ একটি অ্যাক্টিভিটির দুটি ভার্সন দেখানো হয়েছে। একটি ভার্সনে শুধু রঙ ব্যবহার করে ওয়ার্কফ্লোতে দুটি সম্ভাব্য অ্যাকশনের মধ্যে পার্থক্য করা হয়। অন্য ভার্সনে দুটি বিকল্পের মধ্যে পার্থক্য হাইলাইট করার জন্য রঙের পাশাপাশি আকার ও টেক্সট অন্তর্ভুক্ত করার পেশাদার পদ্ধতি ব্যবহার করা হয়:

বাঁদিকে দুটি বৃত্তাকার বোতাম সহ একটি স্ক্রিন রয়েছে, একটি সবুজ ও অপরটি লাল রঙের। ডানদিকে একই স্ক্রিন দেখানো হয়েছে, তবে দুটি বৃত্তাকার বোতামে টেক্সট ও অর্থপূর্ণ আইকন দিয়ে লেবেল করা হয়েছে।
ছবি ১. শুধুমাত্র রঙ ব্যবহার করে (বাঁদিকে) এবং রঙ, আকার ও টেক্সট ব্যবহার করে (ডানদিকে) UI এলিমেন্ট তৈরি করার উদাহরণ।

মিডিয়া কন্টেন্ট আরও অ্যাক্সেসযোগ্য করে তোলা

আপনি যদি এমন কোনও অ্যাপ ডেভেলপ করেন যাতে ভিডিও ক্লিপ বা অডিও রেকর্ডিংয়ের মতো মিডিয়া কন্টেন্ট থাকে, তাহলে বিভিন্ন ধরনের অ্যাক্সেসিবিলিটি সংক্রান্ত প্রয়োজনীয়তা আছে এমন ব্যবহারকারীদের কন্টেন্ট বুঝতে সাহায্য করার চেষ্টা করুন। বিশেষ করে, নিম্নলিখিতগুলি করার চেষ্টা করুন:

  • এমন কন্ট্রোল অন্তর্ভুক্ত করুন যা ব্যবহারকারীদের মিডিয়া পজ বা বন্ধ করতে, ভলিউম পরিবর্তন করতে এবং সাবটাইটেল (ক্যাপশন) টগল করতে দেয়।
  • কোনও ভিডিওতে যদি এমন তথ্য থাকে যা কোনও ওয়ার্কফ্লো সম্পূর্ণ করার জন্য অত্যন্ত গুরুত্বপূর্ণ, তাহলে একই কন্টেন্ট অন্য কোনও ফর্ম্যাটে প্রদান করুন, যেমন ট্রান্সক্রিপ্ট।

অতিরিক্ত রিসোর্স

আপনার অ্যাপকে আরও অ্যাক্সেসযোগ্য করে তোলার ব্যাপারে আরও তথ্যের জন্য, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন:

কোডল্যাবস

কন্টেন্ট দেখে