গ্রিড এবং মিডিয়া কোয়েরি ব্যবহার করে টেবিলটপ পসচার লেআউট

৪ তারকা রেটিং আইকন

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

টেবিলের উপর রাখা ভাঁজযোগ্য ডিভাইসটির উপরের স্ক্রিনে ভিডিও কন্টেন্ট এবং নিচের স্ক্রিনে প্লেব্যাক কন্ট্রোল দেখা যাচ্ছে।
চিত্র ১। টেবিলের উপর রাখার ভঙ্গিটি বিষয়বস্তু এবং ইন্টারেক্টিভ কন্ট্রোলগুলোকে ভৌত ভাঁজ বরাবর বিভক্ত করে।

সর্বোত্তম অনুশীলন

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

  • প্রতিক্রিয়াশীলভাবে টেবিলটপ ভঙ্গি শনাক্ত করুন: ডিভাইসের অবস্থা পর্যবেক্ষণ করতে mediaQuery composable ব্যবহার করুন। যখন ডিভাইসটি টেবিলটপ ভঙ্গিতে ভাঁজ হয় ( windowPosture == Posture.Tabletop ), তখন অ্যাক্টিভিটি পুনরায় চালু করা বা জটিল লাইফসাইকেল হ্যান্ডলিং ছাড়াই আপনার লেআউটটি গতিশীলভাবে পরিবর্তন করুন।
  • Grid দিয়ে লেআউট সাজান: টেবিলটপ অবস্থায়, Grid এপিআই ( 2 rows , 1 column ) ব্যবহার করে মূল ভিজ্যুয়াল কন্টেন্টকে উপরের সারিতে (অ্যাবাভ দ্য ফোল্ড) এবং ইন্টারেক্টিভ কন্ট্রোলগুলোকে নিচের সারিতে (বিলো দ্য ফোল্ড) পরিচ্ছন্নভাবে আলাদা করুন।
  • ওভারলে-এর জন্য অন্তর্নিহিত z-indexing ব্যবহার করুন: স্ট্যান্ডার্ড (নন-টেবিলটপ) পসচারে, প্লেয়ারের উপর কন্ট্রোল ওভারলে করার জন্য একই সেলে একাধিক এরিয়া আইডি অ্যাসাইন করুন। Grid স্বয়ংক্রিয়ভাবে আইটেমগুলিকে তাদের ঘোষণার ক্রম অনুসারে পেছন থেকে সামনের দিকে রেন্ডার করে।
  • সাবলীল রূপান্তর নিশ্চিত করুন: স্ট্যান্ডার্ড ফুল-স্ক্রিন লেআউট এবং টেবিলটপ পসচারের মধ্যে রূপান্তরের সময় স্টেট এবং স্ক্রল পজিশন যেন সংরক্ষিত থাকে, তা নিশ্চিত করুন।

উপকরণ

  • Grid : একটি অভিযোজনযোগ্য লেআউট কন্টেইনার যা আপনাকে কনফিগারযোগ্য সারি এবং কলামে আইটেম স্থাপন করতে দেয়, যা স্ক্রিনের স্বতন্ত্র অঞ্চলে বিষয়বস্তু ভাগ করার জন্য আদর্শ।
  • mediaQuery : একটি Jetpack Compose API যা আপনার কম্পোজেবলগুলোর মধ্যে সরাসরি অ্যাপের বর্তমান উইন্ডো পসচার, সাইজ ক্লাস এবং হার্ডওয়্যারের বৈশিষ্ট্যগুলো জানতে ব্যবহৃত হয়।

পদক্ষেপ

mediaQuery() ব্যবহার করে ডিভাইসের অবস্থান (posture) জানুন। ডিভাইসটি যখন টেবিলটপ অবস্থানে (tabletop posture) থাকবে, তখন আপনার অ্যাপের কন্টেন্টকে দুটি সারি এবং একটি কলাম সহ একটি উল্লম্ব গ্রিডে সাজান, খেয়াল রাখবেন যেন মূল কন্টেন্ট উপরে থাকে এবং কন্ট্রোলগুলো নীচে অ্যাক্সেসযোগ্য থাকে।

১. টেবিলটপ মোডের জন্য গ্রিড কনফিগারেশন নির্ধারণ করুন

একটি কম্পোজেবল ফাংশনের ভিতরে, একটি enum ব্যবহার করে লেআউট এরিয়া আইডিগুলো নির্ধারণ করুন এবং ডিফল্ট ও টেবিলটপ পসচারের জন্য GridConfigurationScope ব্লকগুলো সেট আপ করুন।

defaultConfig এ, উভয় এরিয়া একই সেলে ( row = 1, column = 1 ) বরাদ্দ করা থাকে। Grid ইমপ্লিসিট z-indexing ব্যবহার করে, যেখানে লেআউটে পরে ডিক্লেয়ার করা কম্পোজেবলগুলো আগেরগুলোর উপরে রেন্ডার করা হয়। এর ফলে কন্ট্রোলার অতিরিক্ত কন্টেইনার নেস্টিং ছাড়াই প্লেয়ারের উপর ওভারলে করতে পারে (আরও বিস্তারিত জানতে ‘UI element overlays with Grid’ দেখুন)।

enum class VideoPlayerArea { Player, Controller }

object PlayerGridConfig {
    // Default: Single area layout with overlay (controls on top of player)
    val defaultConfig: GridConfigurationScope.() -> Unit = {
        row(1f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1)
        area(areaId = VideoPlayerArea.Controller, row = 1, column = 1)
    }

    // Tabletop: Two rows splitting content across the fold
    val tabletopConfig: GridConfigurationScope.() -> Unit = {
        row(0.5f)
        row(0.5f)
        column(1f)
        area(areaId = VideoPlayerArea.Player, row = 1, column = 1) // Top half above fold
        area(areaId = VideoPlayerArea.Controller, row = 2, column = 1) // Bottom half below fold
    }
}

২. টেবিলের উপরিভাগের অবস্থান শনাক্ত করুন এবং গ্রিডে কনফিগারেশন প্রয়োগ করুন

windowPosture উপর ভিত্তি করে সক্রিয় কনফিগারেশন নির্বাচন করতে, Gridconfig পাঠাতে এবং কম্পোজেবল কন্টেন্টকে এরিয়া আইডিগুলোর সাথে বাইন্ড করতে mediaQuery ব্যবহার করুন। VideoPlayerArea.Player এর আগে VideoPlayerArea.Controller ডিক্লেয়ার করলে এটি নিশ্চিত হয় যে, যখন উভয়ই defaultConfig এ একটি সেল শেয়ার করে, তখন কন্ট্রোলগুলো প্লেয়ারের উপরে রেন্ডার হবে।

val config = mediaQuery {
    when (windowPosture) {
        Posture.Tabletop -> PlayerGridConfig.tabletopConfig
        else -> PlayerGridConfig.defaultConfig
    }
}

Grid(config = config) {
    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Player)
    ) {
        // VideoPlayerContent
    }

    Box(
        modifier = Modifier
            .gridItem(areaId = VideoPlayerArea.Controller)
    ) {
        // PlaybackControlsContent
    }
}

ফলাফল

mediaQuery এবং Grid সমন্বয়ের মাধ্যমে, আপনার অ্যাপ গতিশীলভাবে শনাক্ত করে যখন কোনো ফোল্ডেবল ডিভাইস আংশিকভাবে ভাঁজ করে টেবিলের উপর রাখার মতো অবস্থায় আসে এবং স্বয়ংক্রিয়ভাবে এর UI-কে ভাঁজ দ্বারা বিভক্ত দুটি কার্যকরী ডিসপ্লে এলাকায় সমন্বয় করে নেয়।

অতিরিক্ত সম্পদ