ফ্লেক্সিবল উইজেট লেআউট প্রদান করা

'কম্পোজ' ফিচার ব্যবহার করে দেখুন
Jetpack Compose হল Android-এর জন্য সাজেস্ট করা UI টুলকিট। Compose-স্টাইল API ব্যবহার করে কীভাবে উইজেট তৈরি করতে হয় তা জানুন।

এই পৃষ্ঠায়, Android 12 (API লেভেল 31)-এ চালু করা উইজেটের সাইজ রিফাইন করা এবং আরও বেশি নমনীয়তা সম্পর্কে বর্ণনা করা হয়েছে। এছাড়াও, কীভাবে আপনার উইজেটের সাইজ নির্ধারণ করবেন তার বিবরণ দেওয়া আছে।

উইজেটের সাইজ ও লেআউটের জন্য উন্নত API ব্যবহার করা

Android 12 (API লেভেল 31) থেকে শুরু করে, আপনি আরও পরিমার্জিত সাইজ অ্যাট্রিবিউট এবং নিম্নলিখিত কাজগুলি করে আরও নমনীয় লেআউট প্রদান করতে পারবেন, যা পরবর্তী বিভাগে বর্ণনা করা হয়েছে:

  1. উইজেটের সাইজ সংক্রান্ত অতিরিক্ত বিধিনিষেধ নির্দিষ্ট করুন।

  2. রেসপন্সিভ লেআউট বা সঠিক লেআউট প্রদান করা।

Android-এর আগের ভার্সনে, OPTION_APPWIDGET_MIN_WIDTH, OPTION_APPWIDGET_MIN_HEIGHT, OPTION_APPWIDGET_MAX_WIDTH, এবং OPTION_APPWIDGET_MAX_HEIGHT এক্সট্রা ব্যবহার করে কোনও উইজেটের সাইজের রেঞ্জ পাওয়া সম্ভব এবং তারপরে উইজেটের সাইজ অনুমান করা যায়, কিন্তু সেই লজিক সব পরিস্থিতিতে কাজ করে না। Android 12 বা এর পরের যেকোনও ভার্সনের জন্য টার্গেট করা উইজেটের ক্ষেত্রে, আমরা রেসপন্সিভ বা সঠিক লেআউট প্রদান করার সাজেশন দিই।

উইজেটের সাইজ সংক্রান্ত অতিরিক্ত সীমাবদ্ধতা উল্লেখ করা

Android 12-এ এমন API যোগ করা হয়েছে যা আপনাকে নিশ্চিত করতে দেয় যে আপনার উইজেট বিভিন্ন স্ক্রিন সাইজের বিভিন্ন ডিভাইসে আরও নির্ভরযোগ্যভাবে সাইজ করা হয়েছে।

আগে থেকে থাকা minWidth, minHeight, minResizeWidth, এবং minResizeHeight অ্যাট্রিবিউট ছাড়াও, নিম্নলিখিত নতুন appwidget-provider অ্যাট্রিবিউট ব্যবহার করুন:

  • targetCellWidth এবং targetCellHeight: লঞ্চার গ্রিড সেলের পরিপ্রেক্ষিতে উইজেটের টার্গেট সাইজ নির্ধারণ করে। এগুলি সংজ্ঞায়িত করা থাকলে, minWidth বা minHeight-এর পরিবর্তে এইসব অ্যাট্রিবিউট ব্যবহার করা হয়।

  • maxResizeWidth ও maxResizeHeight: লঞ্চার ব্যবহারকারীকে উইজেট রিসাইজ করার জন্য সর্বাধিক যে সাইজ সেট করতে দেয় তা নির্ধারণ করে।

নিচের XML থেকে বোঝা যায় যে সাইজিং অ্যাট্রিবিউট কীভাবে ব্যবহার করতে হয়।

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
  android:targetCellWidth="3"
  android:targetCellHeight="2"
  android:maxResizeWidth="250dp"
  android:maxResizeHeight="110dp">
</appwidget-provider>

রেসপন্সিভ লেআউট প্রদান করা

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

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

লেআউটের তালিকা কীভাবে প্রদান করতে হয় তা নিম্নলিখিত কোডের উদাহরণ থেকে জানতে পারবেন।

override fun onUpdate(
    /* ... */
) {
    val smallView = RemoteViews(
        /* ... */
    )
    val tallView = RemoteViews(
        /* ... */
    )
    val wideView = RemoteViews(
        /* ... */
    )

    val viewMapping: Map<SizeF, RemoteViews> = mapOf(
        SizeF(150f, 100f) to smallView,
        SizeF(150f, 200f) to tallView,
        SizeF(215f, 100f) to wideView
    )
    val remoteViews = RemoteViews(viewMapping)

    appWidgetManager.updateAppWidget(id, remoteViews)
}

ধরে নিন উইজেটে নিম্নলিখিত অ্যাট্রিবিউট আছে:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minResizeWidth="160dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="200dp">
</appwidget-provider>

উপরের কোড স্নিপেটটি নিম্নলিখিত বিষয়গুলি বোঝায়:

  • smallView ১৬০dp (minResizeWidth) × ১১০dp (minResizeHeight) থেকে ১৬০dp × ১৯৯dp (পরবর্তী কাট-অফ পয়েন্ট - 1dp) পর্যন্ত কাজ করে।
  • tallView ১৬০dp × ২০০dp থেকে ২১৪dp (পরবর্তী কাট-অফ পয়েন্ট - ১) × ২০০dp পর্যন্ত কাজ করে।
  • wideView ২১৫dp × ১১০dp (minResizeHeight) থেকে ২৫০dp (maxResizeWidth) × ২০০dp (maxResizeHeight) পর্যন্ত কাজ করে।

আপনার উইজেটকে minResizeWidth × minResizeHeight থেকে maxResizeWidth × maxResizeHeight সাইজের মধ্যে হতে হবে। ওই রেঞ্জের মধ্যে, লেআউট পরিবর্তন করার জন্য কাট-অফ পয়েন্ট নির্ধারণ করতে পারবেন।

রেসপন্সিভ লেআউটের উদাহরণ
ছবি ১. রেসপন্সিভ লেআউটের উদাহরণ।

সঠিক লেআউট প্রদান করুন

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

এই সমাধান প্রয়োগ করতে, আপনার অ্যাপকে নিম্নলিখিত ধাপগুলি অনুসরণ করতে হবে:

  1. ওভারলোড AppWidgetProvider.onAppWidgetOptionsChanged(), যেটি সাইজের সেট পরিবর্তন হলে কল করা হয়।

  2. AppWidgetManager.getAppWidgetOptions() কল করুন, যা সাইজ সহ Bundle রিটার্ন করে।

  3. Bundle থেকে AppWidgetManager.OPTION_APPWIDGET_SIZES কী অ্যাক্সেস করুন।

নিচের কোডের উদাহরণ থেকে কীভাবে সঠিক লেআউট প্রদান করতে হয় তা জানতে পারবেন।

override fun onAppWidgetOptionsChanged(
    context: Context,
    appWidgetManager: AppWidgetManager,
    id: Int,
    newOptions: Bundle?
) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, id, newOptions)
    // Get the new sizes.
    val sizes = newOptions?.let {
        BundleCompat.getParcelableArrayList(
            it,
            AppWidgetManager.OPTION_APPWIDGET_SIZES,
            SizeF::class.java
        )
    }
    // Check that the list of sizes is provided by the launcher.
    if (sizes.isNullOrEmpty()) {
        return
    }
    // Map the sizes to the RemoteViews that you want.
    val remoteViews = RemoteViews(sizes.associateWith(::createRemoteViews))
    appWidgetManager.updateAppWidget(id, remoteViews)
}

// Create the RemoteViews for the given size.
private fun createRemoteViews(size: SizeF): RemoteViews {
}

আপনার উইজেটের সাইজ নির্ধারণ করা

Android 12 বা এর পরের যেকোনও ভার্সনে চলে এমন ডিভাইসের জন্য প্রতিটি উইজেটে targetCellWidth ও targetCellHeight অথবা Android-এর সব ভার্সনের জন্য minWidth ও minHeight অবশ্যই থাকতে হবে—এর মাধ্যমে ডিফল্ট হিসেবে এটি কতটা জায়গা ব্যবহার করে তা দেখানো হয়। তবে, ব্যবহারকারীরা তাদের হোম স্ক্রিনে উইজেট যোগ করলে, সাধারণত এটি আপনার নির্দিষ্ট করা ন্যূনতম প্রস্থ ও উচ্চতার চেয়ে বেশি জায়গা নেয়।

Android হোম স্ক্রিন ব্যবহারকারীদের উপলভ্য স্পেসের একটি গ্রিড অফার করে যেখানে তারা উইজেট ও আইকন রাখতে পারেন। এই গ্রিড ডিভাইস অনুযায়ী আলাদা হতে পারে; যেমন, অনেক হ্যান্ডসেটে ৫x৪ গ্রিড থাকে এবং ট্যাবলেটে আরও বড় গ্রিড থাকতে পারে। আপনার উইজেট যোগ করা হলে, Android 12 বা এর পরের যেকোনও ভার্সনে চলা ডিভাইসে সেটির targetCellWidth ও targetCellHeight সংক্রান্ত বিধিনিষেধ অথবা Android 11 (API লেভেল 30) বা এর আগের যেকোনও ভার্সনে চলা ডিভাইসে minWidth ও minHeight সংক্রান্ত বিধিনিষেধ পূরণ করার জন্য প্রয়োজনীয় ন্যূনতম সংখ্যক সেল অনুভূমিক ও উল্লম্বভাবে দখল করার জন্য এটিকে প্রসারিত করা হয়।

ডিভাইস অনুযায়ী সেলের ডাইমেনশন ও অটোমেটিক মার্জিন আলাদা আলাদা হয়। আপনি যতগুলি গ্রিড সেল দখল করতে চান তা বিবেচনা করে, সাধারণ ৫x৪ গ্রিড হ্যান্ডসেটে আপনার উইজেটের ন্যূনতম ডাইমেনশন অনুমান করতে, নিম্নলিখিত টেবিলটি ব্যবহার করুন:

সেলের সংখ্যা (প্রস্থ x উচ্চতা) পোর্ট্রেট মোডে উপলভ্য সাইজ (dp) ল্যান্ডস্কেপ মোডে উপলভ্য সাইজ (dp)
১x১ ৫৭x১০২dp ১২৭x৫১dp
২x১ ১৩০x১০২dp 269x51dp
৩x১ ২০৩x১০২dp 412x51dp
৪x১ ২৭৬x১০২dp ৫৫৪x৫১dp
৫x১ ৩৪৯x১০২dp 697x51dp
৫x২ ৩৪৯x২২০dp ৬৯৭x১১৭dp
৫x৩ ৩৪৯x৩৩৭dp ৬৯৭x১৮৪dp
৫x৪ ৩৪৯x৪৫৫dp ৬৯৭x২৫০dp
... ... ...
n x m (73n - 16) x (118m - 16) (142n - 15) x (66m - 15)

minWidth, minResizeWidth ও maxResizeWidth অ্যাট্রিবিউটের জন্য আপনি যে ভ্যালু প্রদান করেন তা জানাতে পোর্ট্রেট মোড সেল সাইজ ব্যবহার করুন। একইভাবে, minHeight, minResizeHeight ও maxResizeHeight অ্যাট্রিবিউটের জন্য আপনার দেওয়া মান জানাতে ল্যান্ডস্কেপ মোড সেল সাইজ ব্যবহার করুন।

এর কারণ হল, পোর্ট্রেট মোডে সেল প্রস্থ সাধারণত ল্যান্ডস্কেপ মোডের চেয়ে ছোট হয়—এবং একইভাবে, ল্যান্ডস্কেপ মোডে সেল উচ্চতা সাধারণত পোর্ট্রেট মোডের চেয়ে ছোট হয়।

যেমন, আপনি যদি চান যে আপনার উইজেটের প্রস্থ যেন Google Pixel 4-এ একটি সেলে রিসাইজ করা যায়, তাহলে minResizeWidth অ্যাট্রিবিউটের ভ্যালু যেন 57dp-এর চেয়ে ছোট হয় তা নিশ্চিত করতে, আপনাকে minResizeWidth-এর ভ্যালু সর্বাধিক 56dp সেট করতে হবে—কারণ পোর্ট্রেট মোডে একটি সেলের প্রস্থ কমপক্ষে 57dp হয়। একইভাবে, আপনি যদি চান যে একই ডিভাইসে একটি সেলের মধ্যে আপনার উইজেটের উচ্চতা রিসাইজ করা হোক, তাহলে আপনাকে minResizeHeight-এর মান সর্বাধিক ৫০dp সেট করতে হবে, যাতে minResizeHeight অ্যাট্রিবিউটের মান ৫১dp-এর চেয়ে কম হয়—কারণ ল্যান্ডস্কেপ মোডে একটি সেলের উচ্চতা কমপক্ষে ৫১dp হয়।

প্রতিটি উইজেটকে minResizeWidth/minResizeHeight এবং maxResizeWidth/maxResizeHeight অ্যাট্রিবিউটগুলির মধ্যে সাইজের রেঞ্জের মধ্যে রিসাইজ করা যায়, যার অর্থ হল এটিকে এই দুটির মধ্যে যেকোনও সাইজের রেঞ্জের সাথে মানিয়ে নিতে হবে।

যেমন, প্লেসমেন্টে উইজেটের ডিফল্ট সাইজ সেট করতে, আপনি নিম্নলিখিত অ্যাট্রিবিউট সেট করতে পারেন:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:targetCellWidth="3"
    android:targetCellHeight="2"
    android:minWidth="180dp"
    android:minHeight="110dp">
</appwidget-provider>

এর অর্থ হল, targetCellWidth এবং targetCellHeight অ্যাট্রিবিউট অনুযায়ী উইজেটের ডিফল্ট সাইজ হল ৩x২ সেল—অথবা Android 11 বা এর আগের যেকোনও ভার্সনে চলছে এমন ডিভাইসের জন্য minWidth এবং minHeight অ্যাট্রিবিউট অনুযায়ী ১৮০×১১০dp। পরের ক্ষেত্রে, ডিভাইসের উপর নির্ভর করে সেলের সাইজ আলাদা আলাদা হতে পারে।

এছাড়াও, আপনার উইজেটের কাজ করে এমন সাইজের রেঞ্জ সেট করতে, আপনি নিম্নলিখিত অ্যাট্রিবিউট সেট করতে পারবেন:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minResizeWidth="180dp"
    android:minResizeHeight="110dp"
    android:maxResizeWidth="530dp"
    android:maxResizeHeight="450dp">
</appwidget-provider>

আগের অ্যাট্রিবিউট অনুযায়ী, উইজেটের প্রস্থ ১৮০dp থেকে ৫৩০dp পর্যন্ত এবং উচ্চতা ১১০dp থেকে ৪৫০dp পর্যন্ত পরিবর্তন করা যায়। নিম্নলিখিত শর্তগুলি পূরণ হলে, উইজেটটি ৩x২ থেকে ৫x২ সেলে রিসাইজ করা যাবে:

val smallView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_small)
val mediumView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_medium)
val largeView = RemoteViews(context.packageName, R.layout.widget_weather_forecast_large)

val viewMapping: Map<SizeF, RemoteViews> = mapOf(
    SizeF(180f, 110f) to smallView,
    SizeF(270f, 110f) to mediumView,
    SizeF(270f, 280f) to largeView
)

appWidgetManager.updateAppWidget(appWidgetId, RemoteViews(viewMapping))

ধরে নিন যে উইজেটটি পূর্ববর্তী কোড স্নিপেটে সংজ্ঞায়িত রেসপন্সিভ লেআউট ব্যবহার করে। এর অর্থ হল, ১৮০dp (minResizeWidth) x ১১০dp (minResizeHeight) থেকে ২৬৯x২৭৯dp (পরবর্তী কাট-অফ পয়েন্ট - ১) পর্যন্ত R.layout.widget_weather_forecast_small হিসেবে নির্দিষ্ট করা লেআউট ব্যবহার করা হয়। একইভাবে, R.layout.widget_weather_forecast_medium ২৭০x১১০dp থেকে ২৭০x২৭৯dp পর্যন্ত, এবং R.layout.widget_weather_forecast_large ২৭০x২৮০dp থেকে ৫৩০dp (maxResizeWidth) x ৪৫০dp (maxResizeHeight) পর্যন্ত ব্যবহার করা হয়।

ব্যবহারকারী উইজেটের সাইজ পরিবর্তন করলে, সেটির চেহারাও পরিবর্তিত হয় যাতে প্রতিটি সাইজের সেল অনুযায়ী সেটি অ্যাডজাস্ট করতে পারে, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে।

সবচেয়ে ছোট ৩x২-গ্রিড সাইজে আবহাওয়ার উইজেটের উদাহরণ। UI-তে
            লোকেশন (টোকিও), তাপমাত্রা (১৪°) এবং আংশিক মেঘলা
            আবহাওয়ার প্রতীক দেখানো হয়েছে।
ছবি ২. 3x2 R.layout.widget_weather_forecast_small.

৪x২ 'মাঝারি' সাইজের আবহাওয়ার উইজেটের উদাহরণ। উইজেটের সাইজ পরিবর্তন করা
            এইভাবে আগের উইজেটের সাইজের সব UI-এর উপর ভিত্তি করে তৈরি করা হয়,
            এবং 'বেশিরভাগ সময় মেঘলা' লেবেল ও
            বিকেল ৪টে থেকে সন্ধ্যা ৭টা পর্যন্ত তাপমাত্রার পূর্বাভাস যোগ করা হয়।
ছবি ৩. 4x2 R.layout.widget_weather_forecast_medium.

৫x২ 'মাঝারি' সাইজের আবহাওয়ার উইজেটের উদাহরণ। এইভাবে উইজেটের সাইজ পরিবর্তন করলে
            আগের সাইজের মতোই UI পাওয়া যায়, তবে এটি
            একটি সেল দৈর্ঘ্যের সমান করে প্রসারিত করা হয় যাতে এটি আরও বেশি জায়গা নিতে পারে।
ছবি ৪. ৫x২ R.layout.widget_weather_forecast_medium.

৫x৩ 'বড়' সাইজের আবহাওয়ার উইজেটের উদাহরণ। উইজেটের সাইজ পরিবর্তন করা
            এইভাবে আগের উইজেট সাইজের সব UI-এর উপর ভিত্তি করে তৈরি হয়,
            এবং উইজেটের মধ্যে একটি ভিউ যোগ করে যাতে মঙ্গলবার ও বুধবারের
            আবহাওয়া সংক্রান্ত পূর্বাভাস থাকে। রোদ ঝলমলে বা বৃষ্টিময় আবহাওয়ার প্রতীক
            এবং প্রতিটি দিনের সর্বোচ্চ ও সর্বনিম্ন তাপমাত্রা।
ছবি ৫. ৫x৩ R.layout.widget_weather_forecast_large.

৫x৪ 'বড়' সাইজের আবহাওয়ার উইজেটের উদাহরণ। এইভাবে উইজেটের সাইজ পরিবর্তন করলে
            আগের উইজেটের সাইজের সমস্ত UI-এর উপর ভিত্তি করে তৈরি হয়,
            এবং বৃহস্পতিবার ও শুক্রবার যোগ করা হয় (এবং তার সাথে সংশ্লিষ্ট প্রতীক
            যা প্রতিটি দিনের জন্য আবহাওয়ার ধরন এবং সর্বোচ্চ ও সর্বনিম্ন তাপমাত্রা
            নির্দেশ করে)।
ছবি ৬. ৫x৪ R.layout.widget_weather_forecast_large.