ডেস্কটপ উইন্ডোিং সমর্থন করে, ডেস্কটপ উইন্ডোিং সমর্থন করে

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

চিত্র ১-এ, আপনি ডেস্কটপ উইন্ডো সক্ষম করে স্ক্রিনের সংগঠন দেখতে পাচ্ছেন। লক্ষ্য করার মতো বিষয়গুলি:

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

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

যখন একটি অ্যাপ ডেস্কটপ উইন্ডোতে খোলা থাকে, তখন অন্যান্য অ্যাপগুলিও ডেস্কটপ উইন্ডোতে খোলে।

চিত্র ২। ডেস্কটপ উইন্ডোতে প্রবেশ করতে অ্যাপ উইন্ডো হ্যান্ডেল টিপুন, ধরে রাখুন এবং টেনে আনুন।

ব্যবহারকারীরা উইন্ডো হ্যান্ডেলের নীচে প্রদর্শিত মেনু থেকে ডেস্কটপ উইন্ডো চালু করতে পারেন যখন আপনি হ্যান্ডেলটিতে ট্যাপ বা ক্লিক করেন অথবা কীবোর্ড শর্টকাট Meta key (Windows, Command, or Search) + Ctrl + Down ব্যবহার করেন।

ব্যবহারকারীরা সমস্ত সক্রিয় উইন্ডো বন্ধ করে অথবা ডেস্কটপ উইন্ডোর উপরের উইন্ডো হ্যান্ডেলটি ধরে অ্যাপটিকে স্ক্রিনের শীর্ষে টেনে এনে ডেস্কটপ উইন্ডো থেকে বেরিয়ে আসতে পারেন। Meta + H কীবোর্ড শর্টকাট ডেস্কটপ উইন্ডো থেকে বেরিয়ে আসে এবং অ্যাপগুলিকে আবার পূর্ণ স্ক্রিনে চালায়।

ডেস্কটপ উইন্ডোতে ফিরে যেতে, সাম্প্রতিক স্ক্রিনে ডেস্কটপ স্পেস টাইলটি আলতো চাপুন বা ক্লিক করুন।

আকার পরিবর্তন এবং সামঞ্জস্য মোড

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

চিত্র ৩। একটি প্রতিকৃতি-সীমাবদ্ধ অ্যাপের উইন্ডোর আকার ল্যান্ডস্কেপে পরিবর্তন করা হচ্ছে।

নন-সাইজেবল (অর্থাৎ, resizeableActivity = false ) হিসেবে ঘোষিত অ্যাপগুলির UI স্কেল করা হয়েছে, একই আকৃতির অনুপাত বজায় রেখে।

চিত্র ৪. একটি অ-আকার পরিবর্তনযোগ্য অ্যাপের UI উইন্ডোর আকার পরিবর্তনের সাথে সাথে স্কেল হয়।

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

যতক্ষণ না অ্যাপগুলি সম্পূর্ণরূপে প্রতিক্রিয়াশীল ক্যামেরা ভিউফাইন্ডার প্রয়োগের জন্য প্রস্তুত হয়, ততক্ষণ পর্যন্ত বিশেষ চিকিৎসা পদ্ধতিটি আরও মৌলিক ব্যবহারকারীর অভিজ্ঞতা প্রদান করে যা ভুল অনুমানের প্রভাবকে হ্রাস করে।

ক্যামেরা অ্যাপের জন্য সামঞ্জস্যতা মোড সম্পর্কে আরও জানতে, ডিভাইস সামঞ্জস্যতা মোড দেখুন।

চিত্র ৫. উইন্ডোর আকার পরিবর্তনের সাথে সাথে ক্যামেরা ভিউফাইন্ডার তার আকৃতির অনুপাত ধরে রাখে।

কাস্টমাইজযোগ্য হেডার ইনসেট

ডেস্কটপ উইন্ডোতে চলমান সকল অ্যাপের একটি হেডার বার থাকে, এমনকি ইমারসিভ মোডেও । আপনার অ্যাপের কন্টেন্ট হেডার বার দ্বারা অস্পষ্ট কিনা তা যাচাই করুন। হেডার বারটি একটি ক্যাপশন বার ইনসেট টাইপ: WindowInsets.Companion.captionBar() ; ভিউতে, WindowInsets.Type.captionBar() , যা সিস্টেম বারের অংশ।

আপনার অ্যাপে ডিসপ্লে কন্টেন্ট এজ-টু-এজ-এ ইনসেট পরিচালনা এবং Compose-এ উইন্ডো ইনসেট পরিচালনা সম্পর্কে আরও জানতে পারবেন।

হেডার বারটিও কাস্টমাইজযোগ্য। অ্যান্ড্রয়েড 15 অ্যাপিয়ারেন্স টাইপ APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND চালু করেছে যাতে হেডার বারটি স্বচ্ছ হয় এবং অ্যাপগুলি হেডার বারের ভিতরে কাস্টম কন্টেন্ট আঁকতে পারে।

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

অ্যাপগুলি APPEARANCE_LIGHT_CAPTION_BARS ব্যবহার করে হালকা এবং অন্ধকার থিমের জন্য ক্যাপশনের ভিতরে সিস্টেম উপাদানগুলির উপস্থিতি টগল করতে পারে, যেমনটি স্ট্যাটাস বার এবং নেভবার টগল করা হয়।

অ্যান্ড্রয়েড ১৫ এ WindowInsets#getBoundingRects() পদ্ধতিও চালু করা হয়েছে যা অ্যাপগুলিকে ক্যাপশন বারের ইনসেটগুলিকে আরও বিশদে আত্মপরীক্ষা করতে সক্ষম করে। অ্যাপগুলি এমন ক্ষেত্রগুলির মধ্যে পার্থক্য করতে পারে যেখানে সিস্টেম সিস্টেম উপাদানগুলি আঁকে এবং অব্যবহৃত ক্ষেত্রগুলির মধ্যে যেখানে অ্যাপগুলি সিস্টেম উপাদানগুলিকে ওভারল্যাপ না করে কাস্টম সামগ্রী স্থাপন করতে পারে।

API দ্বারা প্রদত্ত Rect অবজেক্টের তালিকা সিস্টেম অঞ্চলগুলিকে নির্দেশ করে যেগুলি এড়ানো উচিত। যেকোনও অবশিষ্ট স্থান (ক্যাপশন বার ইনসেট থেকে আয়তক্ষেত্রগুলি বিয়োগ করে গণনা করা হয়) হল সেই স্থান যেখানে অ্যাপটি সিস্টেম উপাদানগুলিকে ওভারল্যাপ না করে এবং ইনপুট গ্রহণের ক্ষমতা সহ অঙ্কন করতে পারে।

কাস্টম হেডার বাস্তবায়নের আগে এবং পরে Chrome।
চিত্র ৬। কাস্টম হেডার বাস্তবায়নের আগে এবং পরে ক্রোম।

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

// In a custom View's onLayout or a similar lifecycle method
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
    super.onLayout(changed, left, top, right, bottom)
    if (changed) {
        // Calculate the height of your custom header
        val customHeaderHeight = 100 // Replace with your actual header height in pixels

        // Create a Rect covering your custom header area
        val exclusionRect = Rect(0, 0, width, customHeaderHeight)

        // Set the exclusion rects for the system
        systemGestureExclusionRects = listOf(exclusionRect)
    }
}

মাল্টিটাস্কিং এবং মাল্টি-ইনস্ট্যান্স সাপোর্ট

ডেস্কটপ উইন্ডোিংয়ের মূলে রয়েছে মাল্টিটাস্কিং, এবং আপনার অ্যাপের একাধিক উদাহরণের অনুমতি দিলে ব্যবহারকারীর উৎপাদনশীলতা অনেক বেড়ে যেতে পারে।

অ্যান্ড্রয়েড ১৫ PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI প্রবর্তন করেছে, যা অ্যাপগুলিকে নির্দিষ্ট করতে সেট করতে পারে যে সিস্টেম UI অ্যাপটির জন্য দেখানো উচিত যাতে এটি একাধিক ইনস্ট্যান্স হিসাবে চালু করা যায়।

আপনি আপনার অ্যাপের AndroidManifest.xml<activity> ট্যাগের মধ্যে PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI ঘোষণা করতে পারেন:

<activity
    android:name=".MyActivity"
    android:exported="true"
    android:resizeableActivity="true">
    <meta-data
        android:name="android.window.PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI"
        android:value="true" />
</activity>

টেনে আনার অঙ্গভঙ্গির সাহায্যে অ্যাপের উদাহরণগুলি পরিচালনা করুন

মাল্টি-উইন্ডো মোডে, ব্যবহারকারীরা অ্যাপের উইন্ডো থেকে একটি ভিউ এলিমেন্ট টেনে এনে একটি নতুন অ্যাপ ইনস্ট্যান্স শুরু করতে পারেন। ব্যবহারকারীরা একই অ্যাপের ইনস্ট্যান্সের মধ্যে এলিমেন্টগুলি স্থানান্তর করতে পারেন।

চিত্র ৭। ডেস্কটপ উইন্ডো থেকে একটি ট্যাব টেনে এনে Chrome এর একটি নতুন উদাহরণ শুরু করুন।

অ্যান্ড্রয়েড ১৫ ড্র্যাগ আচরণ কাস্টমাইজ করার জন্য দুটি পতাকা প্রবর্তন করেছে:

  • DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG : নির্দেশ করে যে যদি কোনও দৃশ্যমান উইন্ডো ড্রপটি পরিচালনা না করে তবে একটি আনহ্যান্ডেলড ড্র্যাগ সিস্টেমে ডেলিগেট করা উচিত। এই ফ্ল্যাগটি ব্যবহার করার সময়, কলারকে ClipData কে একটি ClipData.Item প্রদান করতে হবে যাতে একটি অপরিবর্তনীয় IntentSender থাকে যা একটি অ্যাক্টিভিটি চালু করার জন্য ( ClipData.Item.Builder#setIntentSender() দেখুন)। বর্তমান স্ক্রিন সাইজ বা উইন্ডোিং মোডের মতো বিষয়গুলির উপর ভিত্তি করে সিস্টেমটি ইনটেন্ট চালু করতে পারে বা নাও করতে পারে। যদি সিস্টেম ইনটেন্ট চালু না করে, তাহলে স্বাভাবিক ড্র্যাগ প্রবাহের মাধ্যমে ইনটেন্ট বাতিল করা হয়।

  • DRAG_FLAG_GLOBAL_SAME_APPLICATION : নির্দেশ করে যে একটি ড্র্যাগ অপারেশন উইন্ডোর সীমানা অতিক্রম করতে পারে (একই অ্যাপ্লিকেশনের একাধিক উদাহরণের জন্য)।

    যখন [ startDragAndDrop() ][20] এই ফ্ল্যাগ সেট দিয়ে কল করা হয়, তখন শুধুমাত্র একই অ্যাপ্লিকেশনের দৃশ্যমান উইন্ডোগুলিই ড্র্যাগ অপারেশনে অংশগ্রহণ করতে এবং ড্র্যাগ করা সামগ্রী গ্রহণ করতে সক্ষম হয়।

নিম্নলিখিত উদাহরণটি startDragAndDrop() দিয়ে এই ফ্ল্যাগগুলি কীভাবে ব্যবহার করতে হয় তা দেখায়:

// Assuming 'view' is the View that initiates the drag
view.setOnLongClickListener {
    // Create an IntentSender for the activity you want to launch
    val launchIntent = Intent(view.context, NewInstanceActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(
        view.context,
        0,
        launchIntent,
        PendingIntent.FLAG_IMMUTABLE // Ensure the PendingIntent is immutable
    )

    // Build the ClipData.Item with the IntentSender
    val item = ClipData.Item.Builder()
        .setIntentSender(pendingIntent.intentSender)
        .build()

    // Create ClipData with a simple description and the item
    val dragData = ClipData(
        ClipDescription("New Instance Drag", arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN)),
        item
    )

    // Combine the drag flags
    val dragFlags = View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG or
                    View.DRAG_FLAG_GLOBAL_SAME_APPLICATION

    // Start the drag operation
    view.startDragAndDrop(
        dragData,                     // The ClipData to drag
        View.DragShadowBuilder(view), // A visual representation of the dragged item
        null,                         // Local state object (not used here)
        dragFlags                     // The drag flags
    )
    true // Indicate that the long click was consumed
}
চিত্র ৮। Chrome অ্যাপের দুটি উদাহরণের মধ্যে একটি ট্যাব সরান।

অতিরিক্ত অপ্টিমাইজেশন

অ্যাপ লঞ্চ কাস্টমাইজ করুন এবং ডেস্কটপ উইন্ডো থেকে পূর্ণ স্ক্রিনে অ্যাপ রূপান্তর করুন।

ডিফল্ট আকার এবং অবস্থান নির্দিষ্ট করুন

সব অ্যাপ, এমনকি যদি আকার পরিবর্তন করা যায়, ব্যবহারকারীর মান প্রদানের জন্য একটি বড় উইন্ডোর প্রয়োজন হয় না। একটি অ্যাক্টিভিটি চালু করার সময় একটি ডিফল্ট আকার এবং অবস্থান নির্দিষ্ট করতে আপনি ActivityOptions#setLaunchBounds() পদ্ধতি ব্যবহার করতে পারেন।

কোনও কার্যকলাপের জন্য লঞ্চ সীমা নির্ধারণের একটি উদাহরণ এখানে দেওয়া হল:

val options = ActivityOptions.makeBasic()

// Define the desired launch bounds (left, top, right, bottom in pixels)
val launchBounds = Rect(100, 100, 700, 600) // Example: 600x500 window at (100,100)

// Apply the launch bounds to the ActivityOptions
options.setLaunchBounds(launchBounds)

// Start the activity with the specified options
val intent = Intent(this, MyActivity::class.java)
startActivity(intent, options.toBundle())

ডেস্কটপ স্পেস থেকে পূর্ণ-স্ক্রিনে প্রবেশ করুন

Activity#requestFullScreenMode() কল করে অ্যাপগুলি পূর্ণ-স্ক্রিনে যেতে পারে। পদ্ধতিটি ডেস্কটপ উইন্ডো থেকে সরাসরি অ্যাপটিকে পূর্ণ স্ক্রিনে প্রদর্শন করে।

কোনও কার্যকলাপ থেকে পূর্ণ-স্ক্রিন মোড অনুরোধ করতে, নিম্নলিখিত কোডটি ব্যবহার করুন:

// In an Activity
fun enterFullScreen() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // Android 15 (U)
        requestFullScreenMode()
    }
}