বিভিন্ন পর্দা মাপ সমর্থন

বিভিন্ন স্ক্রীন মাপের জন্য সমর্থন বিস্তৃত ডিভাইস এবং সর্বাধিক সংখ্যক ব্যবহারকারীর দ্বারা আপনার অ্যাপে অ্যাক্সেস সক্ষম করে।

যতটা সম্ভব স্ক্রীনের আকার সমর্থন করতে, প্রতিক্রিয়াশীল এবং অভিযোজিত হতে আপনার অ্যাপ লেআউট ডিজাইন করুন। প্রতিক্রিয়াশীল/অভিযোজিত লেআউটগুলি স্ক্রীনের আকার নির্বিশেষে একটি অপ্টিমাইজড ব্যবহারকারীর অভিজ্ঞতা প্রদান করে, আপনার অ্যাপটিকে ফোন, ট্যাবলেট, ফোল্ডেবল, ChromeOS ডিভাইস, প্রতিকৃতি এবং ল্যান্ডস্কেপ অভিযোজন এবং মাল্টি-উইন্ডো মোডের মতো পরিবর্তনযোগ্য কনফিগারেশনগুলিকে সামঞ্জস্য করতে সক্ষম করে৷

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

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

স্পষ্টভাবে স্ক্রীন-স্তরের কম্পোজেবলের জন্য বড় লেআউট পরিবর্তন করুন

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

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

ফোন, ফোল্ডেবল, ট্যাবলেট এবং ল্যাপটপ সহ বিভিন্ন ডিভাইস ফর্ম ফ্যাক্টর দেখানো একটি ডায়াগ্রাম।
চিত্র 1. ফোন, ফোল্ডেবল, ট্যাবলেট এবং ল্যাপটপ ফর্ম ফ্যাক্টর

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

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

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

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

@Composable
fun MyApp(
    windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
) {
    // Perform logic on the size class to decide whether to show the top app bar.
    val showTopAppBar = windowSizeClass.windowHeightSizeClass != WindowHeightSizeClass.COMPACT

    // MyScreen knows nothing about window sizes, and performs logic based on a Boolean flag.
    MyScreen(
        showTopAppBar = showTopAppBar,
        /* ... */
    )
}

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

নমনীয় নেস্টেড কম্পোজেবলগুলি পুনরায় ব্যবহারযোগ্য

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

নিম্নলিখিত উদাহরণটি বিবেচনা করুন: একটি নেস্টেড কম্পোজেবল কল্পনা করুন যা একটি তালিকা-বিশদ বিন্যাস প্রয়োগ করে, যা একটি ফলক বা দুটি প্যানে পাশাপাশি দেখাতে পারে।

একটি অ্যাপের স্ক্রিনশট পাশাপাশি দুটি প্যানে দেখা যাচ্ছে।
চিত্র 2. একটি অ্যাপের স্ক্রিনশট একটি সাধারণ তালিকা-বিশদ বিন্যাস দেখাচ্ছে— 1 হল তালিকার এলাকা; 2 , বিস্তারিত এলাকা.

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

@Composable
fun AdaptivePane(
    showOnePane: Boolean,
    /* ... */
) {
    if (showOnePane) {
        OnePane(/* ... */)
    } else {
        TwoPane(/* ... */)
    }
}

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

দুটি ভিন্ন কার্ডের উদাহরণ।
চিত্র 3. সংকীর্ণ কার্ড শুধুমাত্র একটি আইকন এবং শিরোনাম দেখাচ্ছে এবং একটি বিস্তৃত কার্ড আইকন, শিরোনাম এবং সংক্ষিপ্ত বিবরণ দেখাচ্ছে।

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

যেহেতু কম্পোজেবলটি স্ক্রিন-লেভেল কম্পোজেবল নয়, তাই আমাদের পুনরায় ব্যবহারযোগ্যতা সর্বাধিক করার জন্য সরাসরি বর্তমান উইন্ডো মেট্রিক্স ব্যবহার করা উচিত নয়। যদি উপাদানটি প্যাডিংয়ের সাথে স্থাপন করা হয় (যেমন ইনসেটের জন্য), বা যদি নেভিগেশন রেল বা অ্যাপ বারের মতো উপাদান থাকে, তাহলে কম্পোজেবলের জন্য উপলব্ধ স্থানের পরিমাণ অ্যাপে উপলব্ধ সামগ্রিক স্থান থেকে উল্লেখযোগ্যভাবে পৃথক হতে পারে।

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

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

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

@Composable
fun Card(/* ... */) {
    BoxWithConstraints {
        if (maxWidth < 400.dp) {
            Column {
                Image(/* ... */)
                Title(/* ... */)
            }
        } else {
            Row {
                Column {
                    Title(/* ... */)
                    Description(/* ... */)
                }
                Image(/* ... */)
            }
        }
    }
}

নিশ্চিত করুন যে সমস্ত ডেটা বিভিন্ন আকারের জন্য উপলব্ধ

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

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

@Composable
fun Card(
    imageUrl: String,
    title: String,
    description: String
) {
    BoxWithConstraints {
        if (maxWidth < 400.dp) {
            Column {
                Image(imageUrl)
                Title(title)
            }
        } else {
            Row {
                Column {
                    Title(title)
                    Description(description)
                }
                Image(imageUrl)
            }
        }
    }
}

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

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

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

@Composable
fun Card(
    imageUrl: String,
    title: String,
    description: String
) {
    var showMore by remember { mutableStateOf(false) }

    BoxWithConstraints {
        if (maxWidth < 400.dp) {
            Column {
                Image(imageUrl)
                Title(title)
            }
        } else {
            Row {
                Column {
                    Title(title)
                    Description(
                        description = description,
                        showMore = showMore,
                        onShowMoreToggled = { newValue ->
                            showMore = newValue
                        }
                    )
                }
                Image(imageUrl)
            }
        }
    }
}

আরও জানুন

রচনায় কাস্টম লেআউট সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন৷

নমুনা অ্যাপ্লিকেশন

  • বড় স্ক্রীনের ক্যানোনিকাল লেআউটগুলি প্রমাণিত ডিজাইন প্যাটার্নগুলির একটি ভান্ডার যা বড় স্ক্রীন ডিভাইসগুলিতে একটি সর্বোত্তম ব্যবহারকারীর অভিজ্ঞতা প্রদান করে
  • JetNews দেখায় কিভাবে একটি অ্যাপ ডিজাইন করতে হয় যা উপলব্ধ স্থান ব্যবহার করার জন্য তার UI-কে মানিয়ে নেয়
  • উত্তর হল মোবাইল, ট্যাবলেট এবং ফোল্ডেবল সমর্থন করার জন্য একটি অভিযোজিত নমুনা
  • এখন অ্যান্ড্রয়েডে একটি অ্যাপ যা বিভিন্ন স্ক্রীনের আকার সমর্থন করতে অভিযোজিত বিন্যাস ব্যবহার করে

ভিডিও

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}