বিভিন্ন ভাষা ও সংস্কৃতিকে সমর্থন করে

অ্যাপে এমন রিসোর্স থাকে যা নির্দিষ্ট সংস্কৃতির জন্য হতে পারে। যেমন, কোনও অ্যাপে সংস্কৃতি-নির্দিষ্ট স্ট্রিং অন্তর্ভুক্ত থাকতে পারে যা বর্তমান লোকেল অনুযায়ী অনুবাদ করা হয়।

আপনার অ্যাপের বাকি অংশ থেকে সংস্কৃতি-নির্দিষ্ট রিসোর্স আলাদা রাখা একটি ভালো অভ্যাস। Android সিস্টেম লোকেল সেটিং-এর উপর ভিত্তি করে ভাষা- এবং সংস্কৃতি-নির্দিষ্ট রিসোর্স সমাধান করে। আপনার Android প্রোজেক্টের রিসোর্স ডিরেক্টরি ব্যবহার করে আপনি বিভিন্ন লোকেলের জন্য সহায়তা প্রদান করতে পারবেন।

আপনার অ্যাপ ব্যবহারকারীদের সংস্কৃতির সাথে মানানসই রিসোর্স আপনি নির্দিষ্ট করতে পারেন। আপনার ব্যবহারকারীদের ভাষা ও সংস্কৃতির জন্য উপযুক্ত যেকোনও রিসোর্সের ধরন আপনি প্রদান করতে পারেন। যেমন, নিম্নলিখিত স্ক্রিনশটগুলি ডিভাইসের ডিফল্ট en_US লোকেল এবং স্প্যানিশ es_ES লোকেলে স্ট্রিং এবং ড্রয়েবল রিসোর্স প্রদর্শনকারী একটি অ্যাপ দেখায়।

অ্যাপটি বর্তমান লোকেল অনুযায়ী
আলাদা টেক্সট ও আইকন দেখায়

ছবি ১. বর্তমান লোকেলের উপর নির্ভর করে অ্যাপ বিভিন্ন রিসোর্স ব্যবহার করছে।

Android SDK টুল ব্যবহার করে প্রোজেক্ট তৈরি করলে, টুলটি প্রোজেক্টের টপ লেভেলে একটি res/ ডিরেক্টরি তৈরি করে। এই res/ ডিরেক্টরির মধ্যে বিভিন্ন রিসোর্স ধরনের জন্য সাবডিরেক্টরি রয়েছে। এছাড়াও, কিছু ডিফল্ট ফাইল থাকে, যেমন res/values/strings.xml ফাইল, যাতে আপনার স্ট্রিং ভ্যালু থাকে।

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

  • RTL লোকেলগুলির জন্য RTL UI লেআউট ব্যবহার করুন।
  • ফর্ম্যাট করা মেসেজের মধ্যে দেখানো টেক্সট ডেটার দিক শনাক্ত ও ঘোষণা করুন। সাধারণত, আপনি একটি পদ্ধতি কল করতে পারেন, যেমনটি এই গাইডে বর্ণনা করা হয়েছে, যা আপনার জন্য টেক্সট ডেটার দিক নির্ধারণ করে।

লোকেল ডিরেক্টরি ও রিসোর্স ফাইল তৈরি করা

আরও লোকেল যোগ করতে, res/-এর মধ্যে অতিরিক্ত ডিরেক্টরি তৈরি করুন। প্রতিটি ডিরেক্টরির নাম নিম্নলিখিত ফর্ম্যাট অনুযায়ী হতে হবে:

<resource type>-b+<language code>[+<country code>]

যেমন, values-b+es/-এ es ভাষা কোড সহ লোকেলের জন্য স্ট্রিং রিসোর্স রয়েছে। একইভাবে, mipmap-b+es+ES/-এ es ভাষা কোড এবং ES দেশ কোড সহ লোকেলগুলির জন্য আইকন রয়েছে।

রানটাইমে ডিভাইসের লোকেল সেটিংস অনুযায়ী Android উপযুক্ত রিসোর্স লোড করে। আরও তথ্যের জন্য, বিকল্প রিসোর্স প্রদান করুন।

কোন কোন লোকেল সাপোর্ট করবেন তা ঠিক করার পরে, রিসোর্স সাবডিরেক্টরি ও ফাইল তৈরি করুন। যেমন:

MyProject/
    res/
       values/
           strings.xml
       values-b+es/
           strings.xml
       mipmap/
           country_flag.png
       mipmap-b+es+ES/
           country_flag.png

স্থানীয় রিসোর্স দিয়ে রিসোর্স ফাইল পূরণ করুন। লোকালাইজ করা স্ট্রিং ও ইমেজ রিসোর্স ফাইলের উদাহরণ নিচে দেওয়া হল:

/values/strings.xml-এ ইংরেজি স্ট্রিং (ডিফল্ট লোকেল):

<resources>
    <string name="hello_world">Hello World!</string>
</resources>

/values-b+es/strings.xml-এ স্প্যানিশ স্ট্রিং (es লোকেল):

<resources>
    <string name="hello_world">¡Hola Mundo!</string>
</resources>

মার্কিন যুক্তরাষ্ট্রের পতাকার আইকন (ডিফল্ট লোকেল) /mipmap/country_flag.png-এ:

মার্কিন যুক্তরাষ্ট্রের
পতাকার আইকন

ছবি ২. ডিফল্ট (en_US) লোকেলের জন্য ব্যবহৃত আইকন।

/mipmap-b+es+ES/country_flag.png-এ স্প্যানিশ ফ্ল্যাগ আইকন (es_ES লোকেল):

স্পেনের
পতাকার আইকন

ছবি ৩. es_ES লোকেলে ব্যবহৃত আইকন।

মনে রাখবেন: আপনি যেকোনও রিসোর্স টাইপে কনফিগারেশন কোয়ালিফায়ার, যেমন লোকাল কোয়ালিফায়ার ব্যবহার করতে পারবেন। যেমন, আপনি হয়ত আপনার বিটম্যাপ ড্রয়েবলের লোকালাইজ করা ভার্সন দিতে চান। আরও তথ্যের জন্য, আপনার অ্যাপ লোকালাইজ করুন দেখুন।

আপনার অ্যাপে রিসোর্স ব্যবহার করুন

প্রতিটি রিসোর্সের name অ্যাট্রিবিউট ব্যবহার করে আপনার সোর্স কোড এবং অন্যান্য XML ফাইলে রিসোর্সগুলি রেফারেন্স করুন: R.<resource type>.<resource name>. এইভাবে রিসোর্স গ্রহণ করে এমন বিভিন্ন পদ্ধতি রয়েছে, যেমন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

Kotlin

// Get a string resource
val hello = resources.getString(R.string.hello_world)

// Or supply a string resource to a method that requires a string
TextView(this).apply {
    setText(R.string.hello_world)
}

জাভা

// Get a string resource
String hello = getResources().getString(R.string.hello_world);

// Or supply a string resource to a method that requires a string
TextView textView = new TextView(this);
textView.setText(R.string.hello_world);

XML ফাইলে, আপনি সিনট্যাক্স @<resource type>/<resource name> সহ কোনও রিসোর্স উল্লেখ করতে পারেন, যখনই XML অ্যাট্রিবিউট মানানসই ভ্যালু গ্রহণ করে, যেমন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@mipmap/country_flag" />

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

মেসেজে টেক্সট ফর্ম্যাট করা

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

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

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

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

  • মেসেজের শুরুতে যোগ করা টেক্সট:

    PERSON_NAME আপনাকে কল করছেন

  • কোনও সংখ্যা দিয়ে শুরু হওয়া টেক্সট, যেমন ঠিকানা বা টেলিফোন নম্বর:

    987 654-3210

  • এমন টেক্সট যা বিরামচিহ্ন দিয়ে শুরু হয়, যেমন ফোন নম্বর:

    +১৯৮৭৬৫৪৩২১০

  • বিরামচিহ্ন দিয়ে শেষ হওয়া টেক্সট:

    আপনি কি নিশ্চিত?

  • যে টেক্সটে আগে থেকেই উভয় দিক আছে:

    হিব্রু ভাষায় בננה শব্দের অর্থ হল কলা।

উদাহরণ

ধরুন, কোনও অ্যাপকে কখনও কখনও "আপনি কি %s বলতে চেয়েছেন?" মেসেজটি দেখাতে হবে, যেখানে রানটাইমে %s-এর জায়গায় একটি ঠিকানা যোগ করা হবে। অ্যাপটি বিভিন্ন UI লোকেল সাপোর্ট করে, তাই মেসেজটি লোকেল-নির্দিষ্ট রিসোর্স থেকে আসে এবং ডিভাইসটি RTL লোকেলে সেট করা থাকলে RTL দিকনির্দেশ ব্যবহার করে। যেমন, হিব্রু UI-এর জন্য, মেসেজটি এইভাবে দেখানো হয়:

האם התכוונת ל %s?

তবে, সাজেস্ট করা ঠিকানা এমন কোনও ডেটাবেস থেকে আসতে পারে যেখানে লোকেল ভাষায় টেক্সট নেই। যেমন, ঠিকানাটি যদি ক্যালিফোর্নিয়ার কোনও জায়গার হয়, তাহলে ডেটাবেসে সেটি ইংরেজি টেক্সটে দেখা যাবে। আপনি যদি টেক্সটের দিকনির্দেশ সম্পর্কে কোনও ইঙ্গিত না দিয়ে RTL মেসেজে "15 Bay Street, Laurel, CA" ঠিকানাটি যোগ করেন, তাহলে ফলাফলটি প্রত্যাশিত বা সঠিক হবে না:

האם התכוונת ל 15 Bay Street, Laurel, CA?

বাড়ির নম্বর ঠিকানার ডানদিকে দেখা যাচ্ছে, বাঁদিকে নয়। এর ফলে বাড়ির নম্বরটি অদ্ভুত পোস্টাল কোডের মতো দেখায়। একই সমস্যা হতে পারে যদি আপনি RTL টেক্সট এমন একটি মেসেজের মধ্যে অন্তর্ভুক্ত করেন যা LTR টেক্সট ডিরেকশন ব্যবহার করে।

ব্যাখ্যা ও সমাধান

এই উদাহরণে সমস্যাটি ঘটে কারণ টেক্সট ফর্ম্যাটার নির্দিষ্ট করে না যে "১৫" হল ঠিকানার অংশ, তাই সিস্টেম নির্ধারণ করতে পারে না যে "১৫" হল RTL টেক্সটের অংশ যা এটির আগে আসে নাকি LTR টেক্সটের অংশ যা এটির পরে আসে।

এই সমস্যার সমাধান করতে, BidiFormatter ক্লাস থেকে unicodeWrap() পদ্ধতি ব্যবহার করো। এই পদ্ধতিটি স্ট্রিংয়ের দিক শনাক্ত করে এবং এটিকে ইউনিকোড ফর্ম্যাটিং অক্ষরে র‍্যাপ করে যা সেই দিকটি ঘোষণা করে।

নিচে দেওয়া কোড স্নিপেট থেকে বোঝা যাবে যে কীভাবে unicodeWrap() ব্যবহার করতে হয়:

Kotlin

val mySuggestion = "15 Bay Street, Laurel, CA"
val myBidiFormatter: BidiFormatter = BidiFormatter.getInstance()

// The "did_you_mean" localized string resource includes
// a "%s" placeholder for the suggestion.
String.format(getString(R.string.did_you_mean), myBidiFormatter.unicodeWrap(mySuggestion))

জাভা

String mySuggestion = "15 Bay Street, Laurel, CA";
BidiFormatter myBidiFormatter = BidiFormatter.getInstance();

// The "did_you_mean" localized string resource includes
// a "%s" placeholder for the suggestion.
String.format(getString(R.string.did_you_mean),
        myBidiFormatter.unicodeWrap(mySuggestion));

যেহেতু "১৫" এখন LTR হিসেবে ঘোষিত টেক্সটের মধ্যে দেখা যাচ্ছে, তাই এটি সঠিক পজিশনে দেখানো হয়েছে:

האם התכוונת ל 15 Bay Street, Laurel, CA?

আপনি স্থানীয়করণ করা মেসেজে যে টেক্সট যোগ করেন তার প্রতিটি অংশের জন্য unicodeWrap() পদ্ধতি ব্যবহার করুন, তবে নিম্নলিখিত কোনও একটি প্রযোজ্য হলে তা করবেন না:

  • টেক্সটটি মেশিনের ক্ষেত্রে গ্রহণযোগ্য স্ট্রিংয়ে যোগ করা হচ্ছে, যেমন URI বা SQL কোয়েরি।
  • আপনি জানেন যে টেক্সটের অংশটি আগে থেকেই সঠিকভাবে র‍্যাপ করা আছে।

মনে রাখবেন: আপনার অ্যাপ Android 4.3 (API লেভেল ১৮) বা তার চেয়ে উন্নত ভার্সনকে টার্গেট করলে, Android ফ্রেমওয়ার্কে পাওয়া BidiFormatter-এর ভার্সন ব্যবহার করুন। অন্যথায়, সহায়তা লাইব্রেরিতে পাওয়া BidiFormatter-এর ভার্সন ব্যবহার করুন।

সংখ্যা ফর্ম্যাট করুন

আপনার অ্যাপের লজিকে সংখ্যাকে স্ট্রিংয়ে পরিবর্তন করতে মেথড কলের পরিবর্তে ফর্ম্যাট স্ট্রিং ব্যবহার করুন:

Kotlin

var myIntAsString = "$myInt"

জাভা

String myIntAsString = String.format("%d", myInt);

এটি আপনার লোকেলের জন্য উপযুক্তভাবে নম্বর ফর্ম্যাট করে, যার মধ্যে অন্য সেট সংখ্যা ব্যবহার করা অন্তর্ভুক্ত থাকতে পারে।

আপনি যখন String.format() ব্যবহার করে এমন ডিভাইসে SQL কোয়েরি তৈরি করেন, যেটির লোকেল নিজস্ব সংখ্যার সেট ব্যবহার করে, যেমন ফার্সি এবং বেশিরভাগ আরবি লোকেল, তখন কোয়েরির কোনও প্যারামিটার সংখ্যা হলে সমস্যা হয়। কারণ, নম্বরটি লোকালের সংখ্যায় ফর্ম্যাট করা হয়েছে এবং এই সংখ্যাগুলি SQL-এ ভুল।

ASCII-ফর্ম্যাট করা নম্বর সংরক্ষণ করতে এবং SQL কোয়েরি বৈধ রাখতে, আপনাকে এর পরিবর্তে String.format()-এর ওভারলোড করা ভার্সন ব্যবহার করতে হবে যেখানে প্রথম প্যারামিটার হিসেবে লোকেল অন্তর্ভুক্ত থাকে। লোকেল আর্গুমেন্ট ব্যবহার করুন Locale.US।

লেআউট মিররিংয়ের সুবিধা

যারা RTL স্ক্রিপ্ট ব্যবহার করেন তারা RTL ইউজার ইন্টারফেস পছন্দ করেন, যার মধ্যে ডানদিকে অ্যালাইন করা মেনু, ডানদিকে অ্যালাইন করা টেক্সট এবং বাঁদিকে নির্দেশ করা ফরওয়ার্ড তীর অন্তর্ভুক্ত।

ছবি ৪-এ সেটিংস অ্যাপের মধ্যে স্ক্রিনের LTR ভার্সন এবং তার RTL ভার্সনের মধ্যে পার্থক্য দেখানো হয়েছে:

বিজ্ঞপ্তি দেখানোর জায়গাটি স্ক্রিনের উপরে ডানদিকের কোণে ডানদিকে অ্যালাইন করা থাকে,
           অ্যাপ বারের মেনু বোতামটি স্ক্রিনের উপরে বাঁদিকের কোণে থাকে,
           স্ক্রিনের মূল অংশের কন্টেন্ট বাঁদিকে অ্যালাইন করা থাকে এবং
           LTR হিসেবে দেখানো হয় এবং ফিরে যাওয়ার বোতামটি স্ক্রিনের নিচে বাঁদিকের কোণে থাকে এবং
           বাঁদিকে নির্দেশ করে। বিজ্ঞপ্তি দেখানোর জায়গাটি উপরে বাঁদিকের কোণে বাঁদিকে অ্যালাইন করা থাকে,
            অ্যাপ বারে মেনু বোতামটি উপরে ডানদিকের কোণে থাকে, স্ক্রিনের মূল অংশের
            কন্টেন্ট ডানদিকে অ্যালাইন করা থাকে এবং RTL হিসেবে দেখা যায় এবং
            ফিরে যাওয়ার বোতামটি নিচে ডানদিকের কোণে থাকে এবং ডানদিকে
            নির্দেশ করে
ছবি ৪. সেটিংস স্ক্রিনের LTR এবং RTL ভেরিয়েন্ট।

আপনার অ্যাপে RTL সাপোর্ট যোগ করার সময়, নিম্নলিখিত পয়েন্টগুলি মনে রাখবেন:

  • RTL টেক্সট মিররিং শুধুমাত্র Android 4.2 (API লেভেল ১৭) বা তার পরবর্তী যেকোনও ভার্সনে চলা ডিভাইসে ব্যবহার করা অ্যাপে কাজ করে। পুরনো ডিভাইসে টেক্সট মিররিং কীভাবে কাজ করে তা জানতে, এই গাইডে পুরনো অ্যাপের জন্য সহায়তা প্রদান করুন বিকল্প দেখুন।
  • আপনার অ্যাপ RTL টেক্সট ডিরেকশন সাপোর্ট করে কিনা তা পরীক্ষা করতে, এই গাইডে যেভাবে বর্ণনা করা হয়েছে সেইভাবে ডেভেলপার বিকল্প ব্যবহার করে পরীক্ষা করুন এবং যারা RTL স্ক্রিপ্ট ব্যবহার করেন তাদের আপনার অ্যাপ ব্যবহার করার জন্য আমন্ত্রণ জানান।

মনে রাখবেন: লেআউট মিররিং সংক্রান্ত অতিরিক্ত ডিজাইন নির্দেশিকা দেখতে, যার মধ্যে মিরর করার জন্য উপযুক্ত ও অনুপযুক্ত এলিমেন্টের তালিকাও অন্তর্ভুক্ত, উভয়মুখী মেটেরিয়াল ডিজাইন নির্দেশিকা দেখুন।

আপনার অ্যাপে UI লেআউট মিরর করতে, যাতে এটি RTL লোকেলে RTL হিসেবে দেখা যায়, নিম্নলিখিত বিভাগে দেওয়া ধাপগুলি সম্পূর্ণ করুন।

বিল্ড ও ম্যানিফেস্ট ফাইল পরিবর্তন করা

আপনার অ্যাপ মডিউলের build.gradle ফাইল ও অ্যাপ ম্যানিফেস্ট ফাইল নিম্নলিখিতভাবে পরিবর্তন করুন:

build.gradle (Module: app)

গ্ৰুভি

android {
    ...
    defaultConfig {
        targetSdkVersion 17 // Or higher
        ...
    }
}

Kotlin

android {
    ...
    defaultConfig {
        targetSdkVersion(17) // Or higher
        ...
    }
}

AndroidManifest.xml

<manifest ... >
    ...
    <application ...
        android:supportsRtl="true">
    </application>
</manifest>

মনে রাখবেন: আপনার অ্যাপ Android 4.1.1 (API লেভেল ১৬) বা তার নিচের ভার্সনকে টার্গেট করলে, android:supportsRtl অ্যাট্রিবিউট উপেক্ষা করা হয়, এর সাথে আপনার অ্যাপের লেআউট ফাইলে দেখানো যেকোনও start এবং end অ্যাট্রিবিউটের ভ্যালুও উপেক্ষা করা হয়। এই ক্ষেত্রে, আপনার অ্যাপে RTL লেআউট মিররিং অটোমেটিক হয় না।

আগে থেকে থাকা রিসোর্স আপডেট করুন

আপনার আগে থেকে থাকা লেআউট রিসোর্স ফাইলে left এবং right-কে যথাক্রমে start এবং end-এ কনভার্ট করুন। এটি ফ্রেমওয়ার্ককে ব্যবহারকারীর ভাষা সেটিংসের উপর ভিত্তি করে আপনার অ্যাপের UI এলিমেন্টকে অ্যালাইন করতে দেয়।

মনে রাখবেন: আপনার রিসোর্স আপডেট করার আগে, কীভাবে পুরনো অ্যাপের জন্য সহায়তা প্রদান করবেন, অথবা Android 4.1.1 (API লেভেল ১৬) এবং তার নিচের ভার্সনকে টার্গেট করে এমন অ্যাপের জন্য সহায়তা প্রদান করবেন তা জানুন।

ফ্রেমওয়ার্কের RTL অ্যালাইনমেন্টের সুবিধা ব্যবহার করতে, আপনার লেআউট ফাইলের অ্যাট্রিবিউট পরিবর্তন করুন যা সারণী ১-এ দেখানো হয়েছে।

সারণী ১. আপনার অ্যাপে একাধিক টেক্সট ডিরেকশন কাজ করলে ব্যবহার করার জন্য অ্যাট্রিবিউট

শুধুমাত্র LTR-এ কাজ করে এমন অ্যাট্রিবিউট LTR এবং RTL-এ কাজ করে এমন অ্যাট্রিবিউট
android:gravity="left" android:gravity="start"
android:gravity="right" android:gravity="end"
android:layout_gravity="left" android:layout_gravity="start"
android:layout_gravity="right" android:layout_gravity="end"
android:paddingLeft android:paddingStart
android:paddingRight android:paddingEnd
android:drawableLeft android:drawableStart
android:drawableRight android:drawableEnd
android:layout_alignLeft android:layout_alignStart
android:layout_alignRight android:layout_alignEnd
android:layout_marginLeft android:layout_marginStart
android:layout_marginRight android:layout_marginEnd
android:layout_alignParentLeft android:layout_alignParentStart
android:layout_alignParentRight android:layout_alignParentEnd
android:layout_toLeftOf android:layout_toStartOf
android:layout_toRightOf android:layout_toEndOf

টার্গেট SDK ভার্সন, left ও right অ্যাট্রিবিউট সংজ্ঞায়িত করা আছে কিনা এবং start ও end অ্যাট্রিবিউট সংজ্ঞায়িত করা আছে কিনা তার উপর ভিত্তি করে সিস্টেম কীভাবে UI অ্যালাইনমেন্ট অ্যাট্রিবিউট ম্যানেজ করে তা সারণী ২-এ দেখানো হয়েছে।

টেবিল ২। টার্গেট SDK ভার্সন ও নির্দিষ্ট করা অ্যাট্রিবিউটের উপর ভিত্তি করে UI এলিমেন্ট অ্যালাইনমেন্টের আচরণ

Android 4.2
(API লেভেল 17) বা তার পরবর্তী ভার্সন টার্গেট করছেন?
বাঁদিক ও ডানদিক কি নির্দিষ্ট করা আছে? শুরু ও শেষ করার সময় উল্লেখ করা আছে? ফলাফল
হ্যাঁ হ্যাঁ হ্যাঁ start এবং end ব্যবহার করা হয়েছে, left এবং right ওভাররাইড করা হচ্ছে
হ্যাঁ হ্যাঁ না left ও right ব্যবহার করা হয়েছে
হ্যাঁ না হ্যাঁ start ও end ব্যবহার করা হয়েছে
না হ্যাঁ হ্যাঁ left এবং right ব্যবহার করা হয়েছে (start এবং end এড়িয়ে যাওয়া হয়েছে)
না হ্যাঁ না left ও right ব্যবহার করা হয়েছে
না না হ্যাঁ start এবং end-এর সমাধান হল left এবং right

দিকনির্দেশ ও ভাষা-নির্দিষ্ট রিসোর্স যোগ করুন

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

Android 4.2 (API লেভেল 17) এবং তার পরবর্তী ভার্সনে, আপনি -ldrtl (layout-direction-right-to-left) এবং -ldltr (layout-direction-left-to-right) রিসোর্স কোয়ালিফায়ার ব্যবহার করতে পারবেন। আগে থেকে থাকা রিসোর্সের সাথে ব্যাকওয়ার্ড কম্প্যাটিবিলিটি বজায় রাখতে, Android-এর পুরনো ভার্সন সঠিক টেক্সট ডিরেকশন অনুমান করার জন্য রিসোর্সের ল্যাঙ্গুয়েজ কোয়ালিফায়ার ব্যবহার করে।

ধরুন, আপনি RTL স্ক্রিপ্ট সাপোর্ট করার জন্য নির্দিষ্ট লেআউট ফাইল যোগ করতে চান, যেমন হিব্রু, আরবি ও ফার্সি ভাষা। এটি করতে, আপনার res/ ডিরেক্টরিতে একটি layout-ldrtl/ ডিরেক্টরি যোগ করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

res/
    layout/
        main.xml This layout file is loaded by default.
    layout-ldrtl/
        main.xml This layout file is loaded for languages using an
                 RTL text direction, including Arabic, Persian, and Hebrew.

আপনি যদি লেআউটের কোনও নির্দিষ্ট ভার্সন যোগ করতে চান যা শুধুমাত্র আরবি টেক্সটের জন্য ডিজাইন করা হয়েছে, তাহলে আপনার ডিরেক্টরি স্ট্রাকচার নিম্নলিখিতটির মতো দেখতে হবে:

res/
    layout/
        main.xml This layout file is loaded by default.
    layout-ar/
        main.xml This layout file is loaded for Arabic text.
    layout-ldrtl/
        main.xml This layout file is loaded only for non-Arabic
                 languages that use an RTL text direction.

মনে রাখবেন: ভাষা-নির্দিষ্ট রিসোর্স লেআউট-দিকনির্দেশ-নির্দিষ্ট রিসোর্সের চেয়ে বেশি অগ্রাধিকার পায়, যা ডিফল্ট রিসোর্সের চেয়ে বেশি অগ্রাধিকার পায়।

কাজ করে এমন উইজেট ব্যবহার করা

Android 4.2 (API লেভেল 17) থেকে, বেশিরভাগ ফ্রেমওয়ার্ক UI এলিমেন্ট অটোমেটিক RTL টেক্সট ডিরেকশন সাপোর্ট করে। তবে, বেশ কিছু ফ্রেমওয়ার্ক এলিমেন্ট, যেমন ViewPager, RTL টেক্সট ডিরেকশন সাপোর্ট করে না।

হোম-স্ক্রিন উইজেট RTL টেক্সট ডিরেকশনকে সমর্থন করে যতক্ষণ না তাদের সংশ্লিষ্ট ম্যানিফেস্ট ফাইলগুলিতে অ্যাট্রিবিউট অ্যাসাইনমেন্ট android:supportsRtl="true" অন্তর্ভুক্ত থাকে।

পুরনো অ্যাপের জন্য সহায়তা প্রদান করা

আপনার অ্যাপ Android 4.1.1 (API লেভেল ১৬) বা তার আগের কোনও ভার্সনকে টার্গেট করলে, start ও end-এর সাথে left ও right অ্যাট্রিবিউট যোগ করুন।

আপনার লেআউটে RTL টেক্সট ডিরেকশন ব্যবহার করতে হবে কিনা তা চেক করতে, নিম্নলিখিত লজিক ব্যবহার করুন:

Kotlin

private fun shouldUseLayoutRtl(): Boolean {
    return if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
        View.LAYOUT_DIRECTION_RTL == layoutDirection
    } else {
        false
    }
}

জাভা

private boolean shouldUseLayoutRtl() {
    if (android.os.Build.VERSION.SDK_INT >=
            android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
        return View.LAYOUT_DIRECTION_RTL == getLayoutDirection();
    } else {
        return false;
    }
}

মনে রাখবেন: মানানসই হওয়া সংক্রান্ত সমস্যা এড়াতে, Android SDK Build Tools-এর 23.0.1 বা তার পরবর্তী যেকোনও ভার্সন ব্যবহার করুন।

ডেভেলপার বিকল্প ব্যবহার করে পরীক্ষা করা

Android 4.4 (API লেভেল 19) বা তার পরবর্তী যেকোনও ভার্সন চলছে এমন ডিভাইসে, আপনি অন-ডিভাইস ডেভেলপার বিকল্প থেকে RTL লেআউট ডিরেকশন জোর করে চালু করুন বিকল্প চালু করতে পারবেন। এই সেটিং আপনাকে RTL মোডে LTR স্ক্রিপ্ট ব্যবহার করে এমন টেক্সট দেখতে দেয়, যেমন ইংরেজি টেক্সট।

অ্যাপ লজিক আপডেট করুন

এই বিভাগে আপনার অ্যাপের লজিকের নির্দিষ্ট দিকগুলি বর্ণনা করা হয়েছে যা একাধিক টেক্সট ডিরেকশন ম্যানেজ করার জন্য আপনার অ্যাপকে মানিয়ে নেওয়ার সময় আপডেট করতে হবে।

প্রপার্টিতে পরিবর্তন

RTL-সম্পর্কিত যেকোনও প্রপার্টিতে পরিবর্তন ম্যানেজ করতে—যেমন লেআউটের দিক, লেআউটের প্যারামিটার, প্যাডিং, টেক্সটের দিক, টেক্সটের অ্যালাইনমেন্ট বা ড্রয়েবল পজিশনিং— onRtlPropertiesChanged() কলব্যাক ব্যবহার করুন। এই কলব্যাক আপনাকে বর্তমান লেআউটের দিকনির্দেশ পেতে এবং সেই অনুযায়ী কোনও অ্যাক্টিভিটির View অবজেক্ট আপডেট করতে দেয়।

ভিউ

আপনি যদি এমন একটি UI উইজেট তৈরি করেন যা সরাসরি কোনও অ্যাক্টিভিটির ভিউ হায়ারার্কির অংশ নয়, যেমন একটি ডায়ালগ বা টোস্ট-এর মতো UI এলিমেন্ট, তাহলে প্রসঙ্গের উপর নির্ভর করে সঠিক লেআউট ডিরেকশন সেট করুন। এই প্রসেস কীভাবে সম্পূর্ণ করতে হয় তা নিম্নলিখিত কোড স্নিপেট দেখায়:

Kotlin

val config: Configuration = context.resources.configuration
view.layoutDirection = config.layoutDirection

জাভা

final Configuration config =
    getContext().getResources().getConfiguration();
view.setLayoutDirection(config.getLayoutDirection());

View ক্লাসের বেশ কয়েকটি পদ্ধতির ক্ষেত্রে অতিরিক্ত বিবেচনা প্রয়োজন:

onMeasure()
টেক্সটের ডিরেকশনের উপর নির্ভর করে ভিউয়ের পরিমাপ আলাদা হতে পারে।
onLayout()
আপনি নিজের লেআউট ইমপ্লিমেন্টেশন তৈরি করলে, onLayout()-এর আপনার ভার্সনে super() কল করতে হবে এবং RTL স্ক্রিপ্ট সাপোর্ট করার জন্য আপনার কাস্টম লজিক অ্যাডাপ্ট করতে হবে।
onDraw()
আপনি যদি কোনও কাস্টম ভিউ প্রয়োগ করেন বা কোনও ড্রয়িংয়ে উন্নত কার্যকারিতা যোগ করেন, তাহলে RTL স্ক্রিপ্ট সমর্থন করার জন্য আপনাকে কোড আপডেট করতে হবে। আপনার উইজেট RTL মোডে আছে কিনা তা নির্ধারণ করতে নিম্নলিখিত কোডটি ব্যবহার করুন:

Kotlin

// On devices running Android 4.1.1 (API level 16) and lower,
// you can call the isLayoutRtl() system method directly.
fun isLayoutRtl(): Boolean = layoutDirection == LAYOUT_DIRECTION_RTL

জাভা

// On devices running Android 4.1.1 (API level 16) and lower,
// you can call the isLayoutRtl() system method directly.
public boolean isLayoutRtl() {
    return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
}

Drawables

আপনার কাছে এমন কোনও ড্রয়েবল থাকলে যা RTL লেআউটের জন্য মিরর করতে হবে, তাহলে ডিভাইসে চলা Android-এর ভার্সনের উপর ভিত্তি করে এইসব ধাপের মধ্যে কোনও একটি সম্পূর্ণ করুন:

  • Android 4.3 (API লেভেল ১৮) এবং তার আগের যেকোনও ভার্সনে চলা ডিভাইসে, -ldrtl রিসোর্স ফাইল যোগ ও সংজ্ঞায়িত করুন।
  • Android 4.4 (API লেভেল 19) এবং তার পরবর্তী ভার্সনে, আপনার ড্রয়েবল সংজ্ঞায়িত করার সময় android:autoMirrored="true" ব্যবহার করুন, যা সিস্টেমকে আপনার জন্য RTL লেআউট মিররিং ম্যানেজ করতে দেয়।

    মনে রাখবেন: android:autoMirrored অ্যাট্রিবিউট শুধুমাত্র সাধারণ ড্রয়েবলের জন্য কাজ করে যার দ্বিমুখী মিররিং হল সম্পূর্ণ ড্রয়েবলের একটি গ্রাফিক্যাল মিররিং। আপনার ড্রয়েবলে একাধিক এলিমেন্ট থাকলে অথবা আপনার ড্রয়েবল রিফ্লেক্ট করলে এর ব্যাখ্যা পরিবর্তন হয়, আপনি নিজেই মিররিং করতে পারবেন। সম্ভব হলে, আপনার মিরর করা ড্রয়েবল ব্যবহারকারীদের কাছে অর্থপূর্ণ কিনা তা নির্ধারণ করতে একজন দ্বিমুখী বিশেষজ্ঞের সাথে চেক করুন।

গ্র্যাভিটি

আপনার অ্যাপের লেআউট কোডে Gravity.LEFT বা Gravity.RIGHT ব্যবহার করা হলে, এই মানগুলি যথাক্রমে Gravity.START এবং Gravity.END-এ পরিবর্তন করুন।

আপনার কাছে Kotlin বা Java কোড থাকলে যা Gravity.LEFT বা Gravity.RIGHT প্রপার্টির উপর নির্ভর করে, আপনি absoluteGravity সেট করে এই পরিবর্তনের সাথে কাজ করার জন্য এটি মানিয়ে নিতে পারেন যাতে layoutDirection-এর সাথে মেলে।

যেমন, আপনি যদি নিম্নলিখিত কোড ব্যবহার করেন:

Kotlin

when (gravity and Gravity.HORIZONTAL_GRAVITY_MASK) {
    Gravity.LEFT -> {
        // Handle objects that are left-aligned.
    }
    Gravity.RIGHT -> {
        // Handle objects that are right-aligned.
    }
}

জাভা

switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
    case Gravity.LEFT:
        // Handle objects that are left-aligned.
        break;
    case Gravity.RIGHT:
        // Handle objects that are right-aligned.
        break;
}

এটি পরিবর্তন করে নিম্নলিখিতটি করুন:

Kotlin

val absoluteGravity: Int = Gravity.getAbsoluteGravity(gravity, layoutDirection)
when (absoluteGravity and Gravity.HORIZONTAL_GRAVITY_MASK) {
    Gravity.LEFT -> {
        // Handle objects that are left-aligned.
    }
    Gravity.RIGHT -> {
        // Handle objects that are right-aligned.
    }
}

জাভা

final int layoutDirection = getLayoutDirection();
final int absoluteGravity =
        Gravity.getAbsoluteGravity(gravity, layoutDirection);
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
    case Gravity.LEFT:
        // Handle objects that are left-aligned.
        break;
    case Gravity.RIGHT:
        // Handle objects that are right-aligned.
        break;
}

এর অর্থ হল, আপনি নিজের গ্র্যাভিটি ভ্যালুর জন্য start এবং end ব্যবহার করলেও, বাঁদিকে-অ্যালাইন করা এবং ডানদিকে-অ্যালাইন করা ভ্যালু ম্যানেজ করে এমন আগে থেকে থাকা কোড রেখে দিতে পারবেন।

মনে রাখবেন: আপনার গ্র্যাভিটি সেটিংস প্রয়োগ করার সময়, Gravity.apply()-এর ওভারলোড করা ভার্সন ব্যবহার করুন, যার মধ্যে layoutDirection আর্গুমেন্ট অন্তর্ভুক্ত থাকে।

মার্জিন ও প্যাডিং

আপনার অ্যাপে RTL স্ক্রিপ্ট সাপোর্ট করতে, মার্জিন ও প্যাডিং ভ্যালু সম্পর্কিত এইসব পেশাদার পদ্ধতি অনুসরণ করুন:

  • দিক-নির্দেশক অ্যাট্রিবিউট সমতুল্য leftMargin এবং rightMargin-এর পরিবর্তে getMarginStart() এবং getMarginEnd() ব্যবহার করুন।
  • setMargins() ব্যবহার করার সময়, আপনার অ্যাপ RTL স্ক্রিপ্ট শনাক্ত করলে, left এবং right আর্গুমেন্টের ভ্যালু অদলবদল করুন।
  • আপনার অ্যাপে কাস্টম প্যাডিং লজিক থাকলে, setPadding() এবং setPaddingRelative() ওভাররাইড করুন।

প্রতি অ্যাপে ভাষার অভিরুচি সংক্রান্ত সহায়তা

অনেক ক্ষেত্রে, বহুভাষী ব্যবহারকারীরা তাদের সিস্টেমের ভাষা একটি ভাষায় সেট করেন—যেমন ইংরেজি—কিন্তু তারা নির্দিষ্ট অ্যাপের জন্য অন্যান্য ভাষা বেছে নিতে চান, যেমন ডাচ, চীনা বা হিন্দি। এইসব ব্যবহারকারীকে অ্যাপের মাধ্যমে আরও ভালো অভিজ্ঞতা প্রদান করতে, Android 13-এ একাধিক ভাষা কাজ করে এমন অ্যাপের জন্য নিম্নলিখিত ফিচারগুলি নিয়ে আসা হয়েছে:

  • সিস্টেম সেটিংস: একটি সেন্ট্রালাইজড লোকেশন যেখানে ব্যবহারকারীরা প্রতিটি অ্যাপের জন্য পছন্দের ভাষা বেছে নিতে পারেন।

    আপনার অ্যাপে একাধিক ভাষা কাজ করে তা সিস্টেমকে জানাতে, অ্যাপের ম্যানিফেস্টে android:localeConfig অ্যাট্রিবিউট ঘোষণা করতে হবে। আরও জানতে, রিসোর্স ফাইল তৈরি করা এবং আপনার অ্যাপের ম্যানিফেস্ট ফাইলে এটি ঘোষণা করার নির্দেশাবলী দেখুন।

  • অতিরিক্ত API: এই পাবলিক API, যেমন setApplicationLocales() এবং getApplicationLocales() পদ্ধতি LocaleManager-এ, রানটাইমে সিস্টেমের ভাষা থেকে আলাদা ভাষা সেট করতে অ্যাপকে অনুমতি দেয়।

    যেসব অ্যাপ কাস্টম ইন-অ্যাপ ভাষা বাছাইকারী ব্যবহার করে, সেগুলি এই API ব্যবহার করে ব্যবহারকারীদের একই ধরনের অভিজ্ঞতা দিতে পারে, তারা যেখান থেকেই তাদের পছন্দের ভাষা বেছে নিক না কেন। এছাড়াও, পাবলিক API আপনাকে বয়লারপ্লেট কোডের পরিমাণ কমাতে সাহায্য করে এবং এটি স্প্লিট APK-কে সাপোর্ট করে। এছাড়াও, অ্যাপ-লেভেলে ব্যবহারকারীর ভাষা সেটিংস স্টোর করার জন্য অ্যাপের জন্য অটোমেটিক ব্যাক-আপ ফিচার কাজ করে।

    Android-এর আগের ভার্সনের সাথে ব্যাকওয়ার্ড কম্প্যাটিবিলিটির জন্য, AndroidX-এও সমতুল্য API উপলভ্য আছে। আমরা Appcompat 1.6.0-beta01 বা তার পরবর্তী যেকোনও ভার্সন ব্যবহার করার সাজেশন দিই।

    আরও জানতে, নতুন API প্রয়োগ করা সংক্রান্ত নির্দেশাবলী দেখুন।

এছাড়াও দেখুন

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

পুরনো ডিভাইসে কাজ করা সম্পর্কে আরও জানতে, নিম্নলিখিত রিসোর্স দেখুন:

ব্লগ পোস্ট