উইন্ডো আকার ক্লাস ব্যবহার করুন

উইন্ডো আকারের ক্লাস হল মতামতযুক্ত ভিউপোর্ট ব্রেকপয়েন্টের একটি সেট যা আপনাকে প্রতিক্রিয়াশীল/অভিযোজিত লেআউট ডিজাইন, বিকাশ এবং পরীক্ষা করতে সহায়তা করে। ব্রেকপয়েন্ট ভারসাম্য বিন্যাস সরলতা অনন্য ক্ষেত্রে আপনার অ্যাপ্লিকেশন অপ্টিমাইজ করার নমনীয়তা সঙ্গে.

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

চিত্র 1. প্রস্থ-ভিত্তিক উইন্ডো আকারের ক্লাসের উপস্থাপনা।
চিত্র 2. উচ্চতা-ভিত্তিক উইন্ডো আকারের ক্লাসের উপস্থাপনা।

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

সাইজ ক্লাস ব্রেকপয়েন্ট ডিভাইস প্রতিনিধিত্ব
কমপ্যাক্ট প্রস্থ প্রস্থ <600dp 99.96% পোর্ট্রেট ফোন
মাঝারি প্রস্থ 600dp ≤ প্রস্থ < 840dp ট্যাবলেটের 93.73% প্রতিকৃতিতে,

প্রতিকৃতিতে সবচেয়ে বড় খোলা অভ্যন্তরীণ প্রদর্শন

প্রসারিত প্রস্থ প্রস্থ ≥ 840dp ল্যান্ডস্কেপে 97.22% ট্যাবলেট,

আড়াআড়ি মধ্যে সবচেয়ে বড় unfolded ভিতরের প্রদর্শন

কমপ্যাক্ট উচ্চতা উচ্চতা <480dp ল্যান্ডস্কেপে 99.78% ফোন
মাঝারি উচ্চতা 480dp ≤ উচ্চতা <900dp ল্যান্ডস্কেপে 96.56% ট্যাবলেট,

97.59% ফোন পোর্ট্রেট

প্রসারিত উচ্চতা উচ্চতা ≥ 900dp 94.25% ট্যাবলেট প্রতিকৃতিতে

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

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

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

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

আপনি Jetpack WindowManager লাইব্রেরি দ্বারা প্রদত্ত WindowSizeClass#compute() ফাংশন ব্যবহার করে বর্তমান WindowSizeClass গণনা করতে পারেন। নিচের উদাহরণটি দেখায় কিভাবে উইন্ডোর আকারের শ্রেণী গণনা করা যায় এবং যখনই উইন্ডোর আকারের শ্রেণী পরিবর্তিত হয় তখন আপডেটগুলি গ্রহণ করতে হয়:

কোটলিন

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        val container: ViewGroup = binding.container

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(object : View(this) {
            override fun onConfigurationChanged(newConfig: Configuration?) {
                super.onConfigurationChanged(newConfig)
                computeWindowSizeClasses()
            }
        })

        computeWindowSizeClasses()
    }

    private fun computeWindowSizeClasses() {
        val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
        val width = metrics.bounds.width()
        val height = metrics.bounds.height()
        val density = resources.displayMetrics.density
        val windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass
        // COMPACT, MEDIUM, or EXPANDED
        val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

জাভা

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        ViewGroup container = binding.container;

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(new View(this) {
            @Override
            protected void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                computeWindowSizeClasses();
            }
        });

        computeWindowSizeClasses();
    }

    private void computeWindowSizeClasses() {
        WindowMetrics metrics = WindowMetricsCalculator.getOrCreate()
                .computeCurrentWindowMetrics(this);

        int width = metrics.getBounds().width
        int height = metrics.getBounds().height()
        float density = getResources().getDisplayMetrics().density;
        WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass()
        // COMPACT, MEDIUM, or EXPANDED
        WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass()

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

পরীক্ষা উইন্ডো আকার ক্লাস

আপনি লেআউট পরিবর্তন করার সময়, সমস্ত উইন্ডো আকার জুড়ে লেআউট আচরণ পরীক্ষা করুন, বিশেষত কমপ্যাক্ট, মাঝারি, এবং প্রসারিত ব্রেকপয়েন্ট প্রস্থে।

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

পরবর্তী পদক্ষেপ

প্রতিক্রিয়াশীল/অভিযোজিত বিন্যাস তৈরি করতে উইন্ডো আকারের ক্লাসগুলি কীভাবে ব্যবহার করবেন সে সম্পর্কে আরও জানতে, নিম্নলিখিতগুলি দেখুন:

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

,

উইন্ডো আকারের ক্লাস হল মতামতযুক্ত ভিউপোর্ট ব্রেকপয়েন্টের একটি সেট যা আপনাকে প্রতিক্রিয়াশীল/অভিযোজিত লেআউট ডিজাইন, বিকাশ এবং পরীক্ষা করতে সহায়তা করে। ব্রেকপয়েন্ট ভারসাম্য বিন্যাস সরলতা অনন্য ক্ষেত্রে আপনার অ্যাপ্লিকেশন অপ্টিমাইজ করার নমনীয়তা সঙ্গে.

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

চিত্র 1. প্রস্থ-ভিত্তিক উইন্ডো আকারের ক্লাসের উপস্থাপনা।
চিত্র 2. উচ্চতা-ভিত্তিক উইন্ডো আকারের ক্লাসের উপস্থাপনা।

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

সাইজ ক্লাস ব্রেকপয়েন্ট ডিভাইস প্রতিনিধিত্ব
কমপ্যাক্ট প্রস্থ প্রস্থ <600dp 99.96% পোর্ট্রেট ফোন
মাঝারি প্রস্থ 600dp ≤ প্রস্থ < 840dp ট্যাবলেটের 93.73% প্রতিকৃতিতে,

প্রতিকৃতিতে সবচেয়ে বড় খোলা অভ্যন্তরীণ প্রদর্শন

প্রসারিত প্রস্থ প্রস্থ ≥ 840dp ল্যান্ডস্কেপে 97.22% ট্যাবলেট,

আড়াআড়ি মধ্যে সবচেয়ে বড় unfolded ভিতরের প্রদর্শন

কমপ্যাক্ট উচ্চতা উচ্চতা <480dp ল্যান্ডস্কেপে 99.78% ফোন
মাঝারি উচ্চতা 480dp ≤ উচ্চতা <900dp ল্যান্ডস্কেপে 96.56% ট্যাবলেট,

97.59% ফোন পোর্ট্রেট

প্রসারিত উচ্চতা উচ্চতা ≥ 900dp 94.25% ট্যাবলেট প্রতিকৃতিতে

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

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

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

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

আপনি Jetpack WindowManager লাইব্রেরি দ্বারা প্রদত্ত WindowSizeClass#compute() ফাংশন ব্যবহার করে বর্তমান WindowSizeClass গণনা করতে পারেন। নিচের উদাহরণটি দেখায় কিভাবে উইন্ডোর আকারের শ্রেণী গণনা করা যায় এবং যখনই উইন্ডোর আকারের শ্রেণী পরিবর্তিত হয় তখন আপডেটগুলি গ্রহণ করতে হয়:

কোটলিন

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        val container: ViewGroup = binding.container

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(object : View(this) {
            override fun onConfigurationChanged(newConfig: Configuration?) {
                super.onConfigurationChanged(newConfig)
                computeWindowSizeClasses()
            }
        })

        computeWindowSizeClasses()
    }

    private fun computeWindowSizeClasses() {
        val metrics = WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(this)
        val width = metrics.bounds.width()
        val height = metrics.bounds.height()
        val density = resources.displayMetrics.density
        val windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        val widthWindowSizeClass = windowSizeClass.windowWidthSizeClass
        // COMPACT, MEDIUM, or EXPANDED
        val heightWindowSizeClass = windowSizeClass.windowHeightSizeClass

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

জাভা

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        // Replace with a known container that you can safely add a
        // view to where the view won't affect the layout and the view
        // won't be replaced.
        ViewGroup container = binding.container;

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged(). This is required for all
        // activities, even those that don't handle configuration
        // changes. You can't use Activity.onConfigurationChanged(),
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged() is
        // called in those scenarios.
        container.addView(new View(this) {
            @Override
            protected void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                computeWindowSizeClasses();
            }
        });

        computeWindowSizeClasses();
    }

    private void computeWindowSizeClasses() {
        WindowMetrics metrics = WindowMetricsCalculator.getOrCreate()
                .computeCurrentWindowMetrics(this);

        int width = metrics.getBounds().width
        int height = metrics.getBounds().height()
        float density = getResources().getDisplayMetrics().density;
        WindowSizeClass windowSizeClass = WindowSizeClass.compute(width/density, height/density)
        // COMPACT, MEDIUM, or EXPANDED
        WindowWidthSizeClass widthWindowSizeClass = windowSizeClass.getWindowWidthSizeClass()
        // COMPACT, MEDIUM, or EXPANDED
        WindowHeightSizeClass heightWindowSizeClass = windowSizeClass.getWindowHeightSizeClass()

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

পরীক্ষা উইন্ডো আকার ক্লাস

আপনি লেআউট পরিবর্তন করার সময়, সমস্ত উইন্ডো আকার জুড়ে লেআউট আচরণ পরীক্ষা করুন, বিশেষত কমপ্যাক্ট, মাঝারি, এবং প্রসারিত ব্রেকপয়েন্ট প্রস্থে।

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

পরবর্তী পদক্ষেপ

প্রতিক্রিয়াশীল/অভিযোজিত বিন্যাস তৈরি করতে উইন্ডো আকারের ক্লাসগুলি কীভাবে ব্যবহার করবেন সে সম্পর্কে আরও জানতে, নিম্নলিখিতগুলি দেখুন:

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