পণ্যের খবর

Jetpack Compose-এর এপ্রিল '২৬ সংস্করণে নতুন কী আছে

পড়তে ৬ মিনিট
মেঘান মেহতার প্রোফাইল দেখুন
Meghan Mehta ডেভেলপার অ্যাডভোকেট, অ্যান্ড্রয়েড

আজ, Jetpack Compose-এর এপ্রিল '২৬ রিলিজটি স্থিতিশীল হয়েছে। এই রিলিজে রয়েছে কোর কম্পোজ মডিউলের ১.১১ সংস্করণ (সম্পূর্ণ BOM ম্যাপিং দেখুন), শেয়ার্ড এলিমেন্ট ডিবাগ টুল, ট্র্যাকপ্যাড ইভেন্ট এবং আরও অনেক কিছু। এছাড়াও আমাদের কয়েকটি পরীক্ষামূলক API রয়েছে, যেগুলো আপনারা ব্যবহার করে দেখুন এবং সেগুলোর উপর আমাদের মতামত জানান।

আজকের রিলিজটি ব্যবহার করতে, আপনার Compose BOM সংস্করণটি আপগ্রেড করে নিম্নোক্ত সংস্করণে নিয়ে যান:

implementation(platform("androidx.compose:compose-bom:2026.04.01"))

Compose 1.11.0-এর পরিবর্তনসমূহ

টেস্টে কো-রুটিন এক্সিকিউশন

Compose যেভাবে টেস্ট টাইমিং পরিচালনা করে, তাতে আমরা একটি বড় আপডেট আনছি। Compose 1.10-এ ঘোষিত অপ্ট-ইন পিরিয়ডের পর, v2 টেস্টিং API-গুলো এখন ডিফল্ট হিসেবে ব্যবহৃত হবে এবং v1 API-গুলোকে ডেপ্রিকেটেড করা হয়েছে। মূল পরিবর্তনটি হলো ডিফল্ট টেস্ট ডিসপ্যাচারের পরিবর্তন। যেখানে v1 API-গুলো UnconfinedTestDispatcher এর উপর নির্ভর করত, যা কো-রুটিনগুলোকে তাৎক্ষণিকভাবে এক্সিকিউট করত, সেখানে v2 API-গুলো StandardTestDispatcher ব্যবহার করে। এর মানে হলো, আপনার টেস্টে যখন কোনো কো-রুটিন চালু করা হয়, তখন সেটি এখন কিউ-তে জমা হয় এবং ভার্চুয়াল ক্লক এগিয়ে না যাওয়া পর্যন্ত এক্সিকিউট হয় না।

এটি প্রোডাকশন পরিস্থিতিকে আরও ভালোভাবে অনুকরণ করে, কার্যকরভাবে রেস কন্ডিশনগুলো দূর করে এবং আপনার টেস্ট স্যুটকে উল্লেখযোগ্যভাবে আরও শক্তিশালী ও কম ত্রুটিপূর্ণ করে তোলে।

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

শেয়ার করা উপাদানের উন্নতি এবং অ্যানিমেশন টুলিং

আমরা শেয়ার্ড এলিমেন্ট এবং Modifier.animatedBounds এর জন্য কিছু দরকারি ভিজ্যুয়াল ডিবাগিং টুলও যুক্ত করেছি। এখন আপনি আড়ালে ঠিক কী ঘটছে তা দেখতে পারবেন—যেমন টার্গেট বাউন্ডস, অ্যানিমেশন ট্র্যাজেক্টরি এবং কতগুলো ম্যাচ পাওয়া গেছে—যার ফলে কোনো ট্রানজিশন কেন প্রত্যাশা অনুযায়ী কাজ করছে না, তা খুঁজে বের করা অনেক সহজ হয়ে যায়। নতুন টুলিং ব্যবহার করতে, আপনার SharedTransitionLayout-কে LookaheadAnimationVisualDebugging কম্পোজেবল দিয়ে ঘিরে দিন।

LookaheadAnimationVisualDebugging(
    overlayColor = Color(0x4AE91E63),
    isEnabled = true,
    multipleMatchesColor = Color.Green,
    isShowKeylabelEnabled = false,
    unmatchedElementColor = Color.Red,
) {
    SharedTransitionLayout {
        CompositionLocalProvider(
            LocalSharedTransitionScope provides this,
        ) {
            // your content
        }
    }
}

ট্র্যাকপ্যাড ইভেন্টগুলি

আমরা ল্যাপটপের বিল্ট-ইন ট্র্যাকপ্যাড, ট্যাবলেটের জন্য সংযুক্তযোগ্য ট্র্যাকপ্যাড, বা এক্সটার্নাল/ভার্চুয়াল ট্র্যাকপ্যাডের মতো ট্র্যাকপ্যাডগুলির জন্য Compose সাপোর্টকে নতুন করে সাজিয়েছি। বেসিক ট্র্যাকপ্যাড ইভেন্টগুলিকে এখন থেকে সাধারণত PointerType.Mouse ইভেন্ট হিসাবে বিবেচনা করা হবে, যা মাউস এবং ট্র্যাকপ্যাডের আচরণকে ব্যবহারকারীর প্রত্যাশার সাথে আরও ভালোভাবে মেলানোর জন্য সমন্বয় করে। পূর্বে, এই ট্র্যাকপ্যাড ইভেন্টগুলিকে PointerType.Touch এর নকল টাচস্ক্রিন আঙুল হিসাবে ব্যাখ্যা করা হতো, যা ব্যবহারকারীদের জন্য বিভ্রান্তিকর অভিজ্ঞতা তৈরি করত। উদাহরণস্বরূপ, ট্র্যাকপ্যাড দিয়ে ক্লিক এবং ড্র্যাগ করলে সিলেক্ট হওয়ার পরিবর্তে স্ক্রল হয়ে যেত। Compose-এর সর্বশেষ সংস্করণে এই ইভেন্টগুলির পয়েন্টার টাইপ পরিবর্তন করার ফলে, ট্র্যাকপ্যাড দিয়ে ক্লিক এবং ড্র্যাগ করলে আর স্ক্রল হবে না।

আমরা এপিআই ৩৪ (API 34) থেকে প্ল্যাটফর্ম দ্বারা স্বীকৃত আরও জটিল ট্র্যাকপ্যাড জেসচারগুলির জন্য সমর্থনও যুক্ত করেছি, যার মধ্যে দুই আঙুলের সোয়াইপ এবং পিঞ্চ অন্তর্ভুক্ত। ট্র্যাকপ্যাডের সাথে আরও ভালো আচরণের জন্য এই জেসচারগুলি Modifier.scrollable এবং Modifier.transformable এর মতো কম্পোনেন্ট দ্বারা স্বয়ংক্রিয়ভাবে স্বীকৃত হয়।

এই পরিবর্তনগুলো বিল্ট-ইন কম্পোনেন্ট জুড়ে ট্র্যাকপ্যাডের কার্যকারিতা উন্নত করে, যার মধ্যে রয়েছে অপ্রয়োজনীয় টাচ স্লপ অপসারণ, আরও স্বজ্ঞাত ড্র্যাগ-অ্যান্ড-ড্রপ স্টার্টিং জেসচার, টেক্সট ফিল্ডে ডাবল-ক্লিক ও ট্রিপল-ক্লিক সিলেকশন এবং টেক্সট ফিল্ডে ডেস্কটপ-স্টাইলের কনটেক্সট মেনু।

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

beforeAndAfter.webp

কম্পোজিশন হোস্ট ডিফল্ট (কম্পোজ রানটাইম)

আমরা সরাসরি কম্পোজ-রানটাইমের মাধ্যমে হোস্ট-স্তরের পরিষেবা সরবরাহ করার জন্য HostDefaultProvider , LocalHostDefaultProvider , HostDefaultKey এবং ViewTreeHostDefaultKey চালু করেছি। এর ফলে লাইব্রেরিগুলোকে লুকআপের জন্য compose-ui উপর নির্ভর করতে হয় না, যা কোটলিন মাল্টিপ্ল্যাটফর্মকে আরও ভালোভাবে সমর্থন করে। এই মানগুলোকে কম্পোজিশন ট্রির সাথে লিঙ্ক করতে, লাইব্রেরির লেখকরা compositionLocalWithHostDefaultOf ব্যবহার করে একটি CompositionLocal তৈরি করতে পারেন, যা হোস্ট থেকে ডিফল্টগুলো রিজলভ করে।

প্রিভিউ র‍্যাপার

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

PreviewWrapperProvider ইন্টারফেসটি ইমপ্লিমেন্ট করে এবং নতুন @PreviewWrapper অ্যানোটেশনটি প্রয়োগ করার মাধ্যমে, আপনি সহজেই কাস্টম লজিক যুক্ত করতে পারেন, যেমন একটি নির্দিষ্ট Theme প্রয়োগ করা। এই অ্যানোটেশনটি @Composable এবং @Preview বা @MultiPreview দিয়ে অ্যানোটেটেড কোনো ফাংশনে প্রয়োগ করা যায়, যা একটি জেনেরিক ও সহজে ব্যবহারযোগ্য সমাধান প্রদান করে, যা বিভিন্ন প্রিভিউ ফিচারে কাজ করে এবং পুনরাবৃত্তিমূলক কোড উল্লেখযোগ্যভাবে হ্রাস করে।

class ThemeWrapper: PreviewWrapperProvider {
    @Composable
    override fun Wrap(content: @Composable (() -> Unit)) {
        JetsnackTheme {
            content()
        }
    }
}


@PreviewWrapper(ThemeWrapper::class)
@Preview
@Composable
private fun ButtonPreview() {
    // JetsnackTheme in effect
    Button(onClick = {}) {
        Text(text = "Demo")
    }
}

অবচয় এবং অপসারণ

  • Compose 1.10 ব্লগ পোস্টে ঘোষিত ঘোষণা অনুযায়ী, আমরা Modifier.onFirstVisible() বাতিল করছি। এর নামটি প্রায়শই ভুল ধারণার জন্ম দিত, বিশেষ করে লেজি লেআউটের ক্ষেত্রে, যেখানে স্ক্রোল করার সময় এটি একাধিকবার ট্রিগার হতো। আমরা Modifier.onVisibilityChanged() ব্যবহার করার পরামর্শ দিচ্ছি, যা আপনার নির্দিষ্ট ব্যবহারের প্রয়োজন অনুযায়ী ভিজিবিলিটি স্টেটগুলোকে আরও নির্ভুলভাবে ম্যানুয়ালি ট্র্যাক করার সুযোগ দেয়।
  • ComposeFoundationFlags.isTextFieldDpadNavigationEnabled ফ্ল্যাগটি সরিয়ে দেওয়া হয়েছে, কারণ এখন TextFields জন্য ডি-প্যাড নেভিগেশন ডিফল্টরূপে সর্বদা সক্রিয় থাকে। নতুন এই আচরণটি নিশ্চিত করে যে, গেমপ্যাড বা টিভি রিমোট থেকে আসা ডি-প্যাড ইভেন্টগুলো প্রথমে কার্সারকে নির্দিষ্ট দিকে চালিত করবে। কার্সারটি টেক্সটের শেষে পৌঁছালেই কেবল ফোকাস অন্য কোনো এলিমেন্টে যেতে পারবে।

আসন্ন এপিআই

আসন্ন Compose 1.12.0 রিলিজে, compileSdk compileSdk 37 -এ আপগ্রেড করা হবে এবং এর সাথে AGP 9 যুক্ত হবে। Compose-এর উপর নির্ভরশীল সমস্ত অ্যাপ এবং লাইব্রেরিও এই রিকোয়ারমেন্টটি গ্রহণ করবে। আমরা সর্বশেষ প্রকাশিত সংস্করণগুলির সাথে আপ-টু-ডেট থাকার পরামর্শ দিই, কারণ Compose অ্যান্ড্রয়েডের সর্বশেষ ফিচারগুলিতে অ্যাক্সেস দেওয়ার জন্য দ্রুত নতুন compileSdks গ্রহণ করার লক্ষ্য রাখে। বিভিন্ন API লেভেলের জন্য AGP-এর কোন সংস্করণটি সমর্থিত, সে সম্পর্কে আরও তথ্যের জন্য এখানে ডকুমেন্টেশনটি অবশ্যই দেখে নিন।

Compose 1.11.0-এ, নিম্নলিখিত API-গুলো @Experimental হিসেবে চালু করা হয়েছে, এবং আপনারা আপনাদের অ্যাপে এগুলো ব্যবহার করে দেখার পর আপনাদের মতামত জানানোর জন্য আমরা উন্মুখ হয়ে আছি। উল্লেখ্য যে, @Experimental APIs প্রাথমিক মূল্যায়ন ও মতামতের জন্য প্রদান করা হয়েছে এবং ভবিষ্যতের সংস্করণগুলোতে এগুলোতে উল্লেখযোগ্য পরিবর্তন আনা হতে পারে বা এগুলো সরিয়েও ফেলা হতে পারে।

শৈলী (পরীক্ষামূলক)

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

প্রেস করা অবস্থার স্টাইল ব্যাকগ্রাউন্ড ওভাররাইড করার একটি সাধারণ উদাহরণ:

@Composable
fun LoginButton(modifier: Modifier = Modifier) {
    Button(
        onClick = {
            // Login logic
        },
        modifier = modifier,
        style = {
            background(
                Brush.linearGradient(
                    listOf(lightPurple, lightBlue)
                )
            )
            width(75.dp)
            height(50.dp)
            textAlign(TextAlign.Center)
            externalPadding(16.dp)

            pressed {
                background(
                    Brush.linearGradient(
                        listOf(Color.Magenta, Color.Red)
                    )
                )
            }
        }
    ){
        Text(
            text = "Login",
        )
    }
}
স্টাইলস.ওয়েবপি

ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

মিডিয়া কোয়েরি (পরীক্ষামূলক)

নতুন mediaQuery API আপনার UI-কে তার পরিবেশের সাথে খাপ খাইয়ে নেওয়ার জন্য একটি ডিক্লারেটিভ এবং পারফরম্যান্ট উপায় প্রদান করে। এটি একটি UiMediaScope মধ্যে জটিল তথ্য পুনরুদ্ধারকে সহজ শর্তে রূপান্তরিত করে, যা নিশ্চিত করে যে পুনর্গঠন কেবল প্রয়োজনের সময়ই ঘটবে।

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

@Composable
fun isTabletopPosture(
    context: Context = LocalContext.current
): Boolean {
    val windowLayoutInfo by
        WindowInfoTracker
            .getOrCreate(context)
            .windowLayoutInfo(context)
            .collectAsStateWithLifecycle(null)

    return windowLayoutInfo.displayFeatures.any { displayFeature ->
        displayFeature is FoldingFeature &&
            displayFeature.state == FoldingFeature.State.HALF_OPENED &&
            displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
    }
}

@Composable
fun VideoPlayer() {
    if(isTabletopPosture()) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

এখন, UIMediaQuery ব্যবহার করে, আপনি mediaQuery সিনট্যাক্স যোগ করার মাধ্যমে ডিভাইসের বৈশিষ্ট্যগুলো জানতে পারবেন, যেমন ডিভাইসটি টেবিলটপ মোডে আছে কি না।

@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun VideoPlayer() {
    if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
        TabletopLayout()
    } else {
        FlatLayout()
    }
}

ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

গ্রিড (পরীক্ষামূলক)

জেটপ্যাক কম্পোজে জটিল, দ্বি-মাত্রিক লেআউট তৈরির জন্য Grid একটি শক্তিশালী নতুন এপিআই। Row এবং Column রৈখিক ডিজাইনের জন্য চমৎকার হলেও, Grid আপনাকে স্ক্রলযোগ্য তালিকার বাড়তি ঝামেলা ছাড়াই স্ক্রিন-স্তরের আর্কিটেকচার এবং জটিল কম্পোনেন্টের জন্য প্রয়োজনীয় কাঠামোগত নিয়ন্ত্রণ দেয়। Grid আপনাকে ট্র্যাক, গ্যাপ এবং সেল ব্যবহার করে আপনার লেআউট নির্ধারণ করার সুযোগ দেয় এবং সাথে Dp , পার্সেন্টেজ, ইন্ট্রিনসিক কন্টেন্ট সাইজ এবং নমনীয় "Fr" ইউনিটের মতো পরিচিত সাইজিং অপশনও প্রদান করে।

@OptIn(ExperimentalGridApi::class)
@Composable
fun GridExample() {
    Grid(
        config = {
            repeat(4) { column(0.25f) }
            repeat(2) { row(0.5f) }
            gap(16.dp)
        }
    ) {
        Card1(modifier = Modifier.gridItem(rowSpan = 2)
        Card2(modifier = Modifier.gridItem(colmnSpan = 3)
        Card3(modifier = Modifier.gridItem(columnSpan = 2)
        Card4()
    }
}

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

Grid.gif

ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

ফ্লেক্সবক্স (পরীক্ষামূলক)

FlexBox হলো উচ্চ পারফরম্যান্স ও অভিযোজনযোগ্য UI-এর জন্য ডিজাইন করা একটি লেআউট কন্টেইনার। এটি কন্টেইনারের উপলব্ধ আকারের উপর ভিত্তি করে আইটেমের আকার এবং স্থান বণ্টন পরিচালনা করে। এটি আইটেম র‍্যাপিং ( wrap ) এবং মাল্টি-অ্যাক্সিস অ্যালাইনমেন্টের ( justifyContent, alignItems, alignContent ) মতো জটিল কাজগুলো সামলায়। এটি আইটেমগুলোকে কন্টেইনার পূর্ণ করার জন্য বড় ( grow ) বা ছোট ( shrink ) হতে দেয়।

@OptIn(ExperimentalFlexBoxApi::class)
fun FlexBoxWrapping(){
    FlexBox(
        config = {
            wrap(FlexWrap.Wrap)
            gap(8.dp)
        }
    ) {
        RedRoundedBox()
        BlueRoundedBox()
        GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
        OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
        PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
    }
}
AnimationGif.gif

ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

নতুন স্লটটেবিল বাস্তবায়ন (পরীক্ষামূলক)

আমরা SlotTable এর একটি নতুন ইমপ্লিমেন্টেশন চালু করেছি, যা এই রিলিজে ডিফল্টরূপে নিষ্ক্রিয় রয়েছে। SlotTable হলো একটি অভ্যন্তরীণ ডেটা স্ট্রাকচার যা Compose রানটাইম আপনার কম্পোজিশন হায়ারার্কির অবস্থা ট্র্যাক করতে, ইনভ্যালিডেশন/রিকম্পোজিশন ট্র্যাক করতে, মনে রাখা মান সংরক্ষণ করতে এবং রানটাইমে কম্পোজিশনের সমস্ত মেটাডেটা ট্র্যাক করতে ব্যবহার করে। এই নতুন ইমপ্লিমেন্টেশনটি মূলত র‍্যান্ডম এডিটের ক্ষেত্রে পারফরম্যান্স উন্নত করার জন্য ডিজাইন করা হয়েছে।

নতুন SlotTable ব্যবহার করে দেখতে, ComposeRuntimeFlags.isLinkBufferComposerEnabled সক্রিয় করুন।

আজই কোডিং শুরু করুন!

Jetpack Compose-এ এতগুলো চমৎকার নতুন API এবং আরও অনেক কিছু আসতে থাকায়, Jetpack Compose-এ স্থানান্তরিত হওয়ার জন্য এর চেয়ে ভালো সময় আর হতে পারে না। বরাবরের মতোই, আমরা আপনার মতামত এবং ফিচার অনুরোধকে গুরুত্ব দিই (বিশেষ করে @Experimental ফিচারগুলোর উপর, যেগুলো এখনও তৈরি হচ্ছে) — অনুগ্রহ করে সেগুলো এখানে জমা দিন। হ্যাপি কম্পোজিং!

    লিখেছেন:
    পড়তে থাকুন
    ,
    পণ্যের খবর

    Jetpack Compose-এর এপ্রিল '২৬ সংস্করণে নতুন কী আছে

    পড়তে ৬ মিনিট
    মেঘান মেহতার প্রোফাইল দেখুন
    Meghan Mehta ডেভেলপার অ্যাডভোকেট, অ্যান্ড্রয়েড

    আজ, Jetpack Compose-এর এপ্রিল '২৬ রিলিজটি স্থিতিশীল হয়েছে। এই রিলিজে রয়েছে কোর কম্পোজ মডিউলের ১.১১ সংস্করণ (সম্পূর্ণ BOM ম্যাপিং দেখুন), শেয়ার্ড এলিমেন্ট ডিবাগ টুল, ট্র্যাকপ্যাড ইভেন্ট এবং আরও অনেক কিছু। এছাড়াও আমাদের কয়েকটি পরীক্ষামূলক API রয়েছে, যেগুলো আপনারা ব্যবহার করে দেখুন এবং সেগুলোর উপর আমাদের মতামত জানান।

    আজকের রিলিজটি ব্যবহার করতে, আপনার Compose BOM সংস্করণটি আপগ্রেড করে নিম্নোক্ত সংস্করণে নিয়ে যান:

    implementation(platform("androidx.compose:compose-bom:2026.04.01"))

    Compose 1.11.0-এর পরিবর্তনসমূহ

    টেস্টে কো-রুটিন এক্সিকিউশন

    Compose যেভাবে টেস্ট টাইমিং পরিচালনা করে, তাতে আমরা একটি বড় আপডেট আনছি। Compose 1.10-এ ঘোষিত অপ্ট-ইন পিরিয়ডের পর, v2 টেস্টিং API-গুলো এখন ডিফল্ট হিসেবে ব্যবহৃত হবে এবং v1 API-গুলোকে ডেপ্রিকেটেড করা হয়েছে। মূল পরিবর্তনটি হলো ডিফল্ট টেস্ট ডিসপ্যাচারের পরিবর্তন। যেখানে v1 API-গুলো UnconfinedTestDispatcher এর উপর নির্ভর করত, যা কো-রুটিনগুলোকে তাৎক্ষণিকভাবে এক্সিকিউট করত, সেখানে v2 API-গুলো StandardTestDispatcher ব্যবহার করে। এর মানে হলো, আপনার টেস্টে যখন কোনো কো-রুটিন চালু করা হয়, তখন সেটি এখন কিউ-তে জমা হয় এবং ভার্চুয়াল ক্লক এগিয়ে না যাওয়া পর্যন্ত এক্সিকিউট হয় না।

    এটি প্রোডাকশন পরিস্থিতিকে আরও ভালোভাবে অনুকরণ করে, কার্যকরভাবে রেস কন্ডিশনগুলো দূর করে এবং আপনার টেস্ট স্যুটকে উল্লেখযোগ্যভাবে আরও শক্তিশালী ও কম ত্রুটিপূর্ণ করে তোলে।

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

    শেয়ার করা উপাদানের উন্নতি এবং অ্যানিমেশন টুলিং

    আমরা শেয়ার্ড এলিমেন্ট এবং Modifier.animatedBounds এর জন্য কিছু দরকারি ভিজ্যুয়াল ডিবাগিং টুলও যুক্ত করেছি। এখন আপনি আড়ালে ঠিক কী ঘটছে তা দেখতে পারবেন—যেমন টার্গেট বাউন্ডস, অ্যানিমেশন ট্র্যাজেক্টরি এবং কতগুলো ম্যাচ পাওয়া গেছে—যার ফলে কোনো ট্রানজিশন কেন প্রত্যাশা অনুযায়ী কাজ করছে না, তা খুঁজে বের করা অনেক সহজ হয়ে যায়। নতুন টুলিং ব্যবহার করতে, আপনার SharedTransitionLayout-কে LookaheadAnimationVisualDebugging কম্পোজেবল দিয়ে ঘিরে দিন।

    LookaheadAnimationVisualDebugging(
        overlayColor = Color(0x4AE91E63),
        isEnabled = true,
        multipleMatchesColor = Color.Green,
        isShowKeylabelEnabled = false,
        unmatchedElementColor = Color.Red,
    ) {
        SharedTransitionLayout {
            CompositionLocalProvider(
                LocalSharedTransitionScope provides this,
            ) {
                // your content
            }
        }
    }

    ট্র্যাকপ্যাড ইভেন্টগুলি

    আমরা ল্যাপটপের বিল্ট-ইন ট্র্যাকপ্যাড, ট্যাবলেটের জন্য সংযুক্তযোগ্য ট্র্যাকপ্যাড, বা এক্সটার্নাল/ভার্চুয়াল ট্র্যাকপ্যাডের মতো ট্র্যাকপ্যাডগুলির জন্য Compose সাপোর্টকে নতুন করে সাজিয়েছি। বেসিক ট্র্যাকপ্যাড ইভেন্টগুলিকে এখন থেকে সাধারণত PointerType.Mouse ইভেন্ট হিসাবে বিবেচনা করা হবে, যা মাউস এবং ট্র্যাকপ্যাডের আচরণকে ব্যবহারকারীর প্রত্যাশার সাথে আরও ভালোভাবে মেলানোর জন্য সমন্বয় করে। পূর্বে, এই ট্র্যাকপ্যাড ইভেন্টগুলিকে PointerType.Touch এর নকল টাচস্ক্রিন আঙুল হিসাবে ব্যাখ্যা করা হতো, যা ব্যবহারকারীদের জন্য বিভ্রান্তিকর অভিজ্ঞতা তৈরি করত। উদাহরণস্বরূপ, ট্র্যাকপ্যাড দিয়ে ক্লিক এবং ড্র্যাগ করলে সিলেক্ট হওয়ার পরিবর্তে স্ক্রল হয়ে যেত। Compose-এর সর্বশেষ সংস্করণে এই ইভেন্টগুলির পয়েন্টার টাইপ পরিবর্তন করার ফলে, ট্র্যাকপ্যাড দিয়ে ক্লিক এবং ড্র্যাগ করলে আর স্ক্রল হবে না।

    আমরা এপিআই ৩৪ (API 34) থেকে প্ল্যাটফর্ম দ্বারা স্বীকৃত আরও জটিল ট্র্যাকপ্যাড জেসচারগুলির জন্য সমর্থনও যুক্ত করেছি, যার মধ্যে দুই আঙুলের সোয়াইপ এবং পিঞ্চ অন্তর্ভুক্ত। ট্র্যাকপ্যাডের সাথে আরও ভালো আচরণের জন্য এই জেসচারগুলি Modifier.scrollable এবং Modifier.transformable এর মতো কম্পোনেন্ট দ্বারা স্বয়ংক্রিয়ভাবে স্বীকৃত হয়।

    এই পরিবর্তনগুলো বিল্ট-ইন কম্পোনেন্ট জুড়ে ট্র্যাকপ্যাডের কার্যকারিতা উন্নত করে, যার মধ্যে রয়েছে অপ্রয়োজনীয় টাচ স্লপ অপসারণ, আরও স্বজ্ঞাত ড্র্যাগ-অ্যান্ড-ড্রপ স্টার্টিং জেসচার, টেক্সট ফিল্ডে ডাবল-ক্লিক ও ট্রিপল-ক্লিক সিলেকশন এবং টেক্সট ফিল্ডে ডেস্কটপ-স্টাইলের কনটেক্সট মেনু।

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

    beforeAndAfter.webp

    কম্পোজিশন হোস্ট ডিফল্ট (কম্পোজ রানটাইম)

    আমরা সরাসরি কম্পোজ-রানটাইমের মাধ্যমে হোস্ট-স্তরের পরিষেবা সরবরাহ করার জন্য HostDefaultProvider , LocalHostDefaultProvider , HostDefaultKey এবং ViewTreeHostDefaultKey চালু করেছি। এর ফলে লাইব্রেরিগুলোকে লুকআপের জন্য compose-ui উপর নির্ভর করতে হয় না, যা কোটলিন মাল্টিপ্ল্যাটফর্মকে আরও ভালোভাবে সমর্থন করে। এই মানগুলোকে কম্পোজিশন ট্রির সাথে লিঙ্ক করতে, লাইব্রেরির লেখকরা compositionLocalWithHostDefaultOf ব্যবহার করে একটি CompositionLocal তৈরি করতে পারেন, যা হোস্ট থেকে ডিফল্টগুলো রিজলভ করে।

    প্রিভিউ র‍্যাপার

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

    PreviewWrapperProvider ইন্টারফেসটি ইমপ্লিমেন্ট করে এবং নতুন @PreviewWrapper অ্যানোটেশনটি প্রয়োগ করার মাধ্যমে, আপনি সহজেই কাস্টম লজিক যুক্ত করতে পারেন, যেমন একটি নির্দিষ্ট Theme প্রয়োগ করা। এই অ্যানোটেশনটি @Composable এবং @Preview বা @MultiPreview দিয়ে অ্যানোটেটেড কোনো ফাংশনে প্রয়োগ করা যায়, যা একটি জেনেরিক ও সহজে ব্যবহারযোগ্য সমাধান প্রদান করে, যা বিভিন্ন প্রিভিউ ফিচারে কাজ করে এবং পুনরাবৃত্তিমূলক কোড উল্লেখযোগ্যভাবে হ্রাস করে।

    class ThemeWrapper: PreviewWrapperProvider {
        @Composable
        override fun Wrap(content: @Composable (() -> Unit)) {
            JetsnackTheme {
                content()
            }
        }
    }
    
    
    @PreviewWrapper(ThemeWrapper::class)
    @Preview
    @Composable
    private fun ButtonPreview() {
        // JetsnackTheme in effect
        Button(onClick = {}) {
            Text(text = "Demo")
        }
    }

    অবচয় এবং অপসারণ

    • Compose 1.10 ব্লগ পোস্টে ঘোষিত ঘোষণা অনুযায়ী, আমরা Modifier.onFirstVisible() বাতিল করছি। এর নামটি প্রায়শই ভুল ধারণার জন্ম দিত, বিশেষ করে লেজি লেআউটের ক্ষেত্রে, যেখানে স্ক্রোল করার সময় এটি একাধিকবার ট্রিগার হতো। আমরা Modifier.onVisibilityChanged() ব্যবহার করার পরামর্শ দিচ্ছি, যা আপনার নির্দিষ্ট ব্যবহারের প্রয়োজন অনুযায়ী ভিজিবিলিটি স্টেটগুলোকে আরও নির্ভুলভাবে ম্যানুয়ালি ট্র্যাক করার সুযোগ দেয়।
    • ComposeFoundationFlags.isTextFieldDpadNavigationEnabled ফ্ল্যাগটি সরিয়ে দেওয়া হয়েছে, কারণ এখন TextFields জন্য ডি-প্যাড নেভিগেশন ডিফল্টরূপে সর্বদা সক্রিয় থাকে। নতুন এই আচরণটি নিশ্চিত করে যে, গেমপ্যাড বা টিভি রিমোট থেকে আসা ডি-প্যাড ইভেন্টগুলো প্রথমে কার্সারকে নির্দিষ্ট দিকে চালিত করবে। কার্সারটি টেক্সটের শেষে পৌঁছালেই কেবল ফোকাস অন্য কোনো এলিমেন্টে যেতে পারবে।

    আসন্ন এপিআই

    আসন্ন Compose 1.12.0 রিলিজে, compileSdk compileSdk 37 -এ আপগ্রেড করা হবে এবং এর সাথে AGP 9 যুক্ত হবে। Compose-এর উপর নির্ভরশীল সমস্ত অ্যাপ এবং লাইব্রেরিও এই রিকোয়ারমেন্টটি গ্রহণ করবে। আমরা সর্বশেষ প্রকাশিত সংস্করণগুলির সাথে আপ-টু-ডেট থাকার পরামর্শ দিই, কারণ Compose অ্যান্ড্রয়েডের সর্বশেষ ফিচারগুলিতে অ্যাক্সেস দেওয়ার জন্য দ্রুত নতুন compileSdks গ্রহণ করার লক্ষ্য রাখে। বিভিন্ন API লেভেলের জন্য AGP-এর কোন সংস্করণটি সমর্থিত, সে সম্পর্কে আরও তথ্যের জন্য এখানে ডকুমেন্টেশনটি অবশ্যই দেখে নিন।

    Compose 1.11.0-এ, নিম্নলিখিত API-গুলো @Experimental হিসেবে চালু করা হয়েছে, এবং আপনারা আপনাদের অ্যাপে এগুলো ব্যবহার করে দেখার পর আপনাদের মতামত জানানোর জন্য আমরা উন্মুখ হয়ে আছি। উল্লেখ্য যে, @Experimental APIs প্রাথমিক মূল্যায়ন ও মতামতের জন্য প্রদান করা হয়েছে এবং ভবিষ্যতের সংস্করণগুলোতে এগুলোতে উল্লেখযোগ্য পরিবর্তন আনা হতে পারে বা এগুলো সরিয়েও ফেলা হতে পারে।

    শৈলী (পরীক্ষামূলক)

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

    প্রেস করা অবস্থার স্টাইল ব্যাকগ্রাউন্ড ওভাররাইড করার একটি সাধারণ উদাহরণ:

    @Composable
    fun LoginButton(modifier: Modifier = Modifier) {
        Button(
            onClick = {
                // Login logic
            },
            modifier = modifier,
            style = {
                background(
                    Brush.linearGradient(
                        listOf(lightPurple, lightBlue)
                    )
                )
                width(75.dp)
                height(50.dp)
                textAlign(TextAlign.Center)
                externalPadding(16.dp)
    
                pressed {
                    background(
                        Brush.linearGradient(
                            listOf(Color.Magenta, Color.Red)
                        )
                    )
                }
            }
        ){
            Text(
                text = "Login",
            )
        }
    }
    স্টাইলস.ওয়েবপি

    ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

    মিডিয়া কোয়েরি (পরীক্ষামূলক)

    নতুন mediaQuery API আপনার UI-কে তার পরিবেশের সাথে খাপ খাইয়ে নেওয়ার জন্য একটি ডিক্লারেটিভ এবং পারফরম্যান্ট উপায় প্রদান করে। এটি একটি UiMediaScope মধ্যে জটিল তথ্য পুনরুদ্ধারকে সহজ শর্তে রূপান্তরিত করে, যা নিশ্চিত করে যে পুনর্গঠন কেবল প্রয়োজনের সময়ই ঘটবে।

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

    @Composable
    fun isTabletopPosture(
        context: Context = LocalContext.current
    ): Boolean {
        val windowLayoutInfo by
            WindowInfoTracker
                .getOrCreate(context)
                .windowLayoutInfo(context)
                .collectAsStateWithLifecycle(null)
    
        return windowLayoutInfo.displayFeatures.any { displayFeature ->
            displayFeature is FoldingFeature &&
                displayFeature.state == FoldingFeature.State.HALF_OPENED &&
                displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
        }
    }
    
    @Composable
    fun VideoPlayer() {
        if(isTabletopPosture()) {
            TabletopLayout()
        } else {
            FlatLayout()
        }
    }

    এখন, UIMediaQuery ব্যবহার করে, আপনি mediaQuery সিনট্যাক্স যোগ করার মাধ্যমে ডিভাইসের বৈশিষ্ট্যগুলো জানতে পারবেন, যেমন ডিভাইসটি টেবিলটপ মোডে আছে কি না।

    @OptIn(ExperimentalMediaQueryApi::class)
    @Composable
    fun VideoPlayer() {
        if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
            TabletopLayout()
        } else {
            FlatLayout()
        }
    }

    ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

    গ্রিড (পরীক্ষামূলক)

    জেটপ্যাক কম্পোজে জটিল, দ্বি-মাত্রিক লেআউট তৈরির জন্য Grid একটি শক্তিশালী নতুন এপিআই। Row এবং Column রৈখিক ডিজাইনের জন্য চমৎকার হলেও, Grid আপনাকে স্ক্রলযোগ্য তালিকার বাড়তি ঝামেলা ছাড়াই স্ক্রিন-স্তরের আর্কিটেকচার এবং জটিল কম্পোনেন্টের জন্য প্রয়োজনীয় কাঠামোগত নিয়ন্ত্রণ দেয়। Grid আপনাকে ট্র্যাক, গ্যাপ এবং সেল ব্যবহার করে আপনার লেআউট নির্ধারণ করার সুযোগ দেয় এবং সাথে Dp , পার্সেন্টেজ, ইন্ট্রিনসিক কন্টেন্ট সাইজ এবং নমনীয় "Fr" ইউনিটের মতো পরিচিত সাইজিং অপশনও প্রদান করে।

    @OptIn(ExperimentalGridApi::class)
    @Composable
    fun GridExample() {
        Grid(
            config = {
                repeat(4) { column(0.25f) }
                repeat(2) { row(0.5f) }
                gap(16.dp)
            }
        ) {
            Card1(modifier = Modifier.gridItem(rowSpan = 2)
            Card2(modifier = Modifier.gridItem(colmnSpan = 3)
            Card3(modifier = Modifier.gridItem(columnSpan = 2)
            Card4()
        }
    }

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

    Grid.gif

    ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

    ফ্লেক্সবক্স (পরীক্ষামূলক)

    FlexBox হলো উচ্চ পারফরম্যান্স ও অভিযোজনযোগ্য UI-এর জন্য ডিজাইন করা একটি লেআউট কন্টেইনার। এটি কন্টেইনারের উপলব্ধ আকারের উপর ভিত্তি করে আইটেমের আকার এবং স্থান বণ্টন পরিচালনা করে। এটি আইটেম র‍্যাপিং ( wrap ) এবং মাল্টি-অ্যাক্সিস অ্যালাইনমেন্টের ( justifyContent, alignItems, alignContent ) মতো জটিল কাজগুলো সামলায়। এটি আইটেমগুলোকে কন্টেইনার পূর্ণ করার জন্য বড় ( grow ) বা ছোট ( shrink ) হতে দেয়।

    @OptIn(ExperimentalFlexBoxApi::class)
    fun FlexBoxWrapping(){
        FlexBox(
            config = {
                wrap(FlexWrap.Wrap)
                gap(8.dp)
            }
        ) {
            RedRoundedBox()
            BlueRoundedBox()
            GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
            OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
            PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
        }
    }
    AnimationGif.gif

    ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

    নতুন স্লটটেবিল বাস্তবায়ন (পরীক্ষামূলক)

    আমরা SlotTable এর একটি নতুন ইমপ্লিমেন্টেশন চালু করেছি, যা এই রিলিজে ডিফল্টরূপে নিষ্ক্রিয় রয়েছে। SlotTable হলো একটি অভ্যন্তরীণ ডেটা স্ট্রাকচার যা Compose রানটাইম আপনার কম্পোজিশন হায়ারার্কির অবস্থা ট্র্যাক করতে, ইনভ্যালিডেশন/রিকম্পোজিশন ট্র্যাক করতে, মনে রাখা মান সংরক্ষণ করতে এবং রানটাইমে কম্পোজিশনের সমস্ত মেটাডেটা ট্র্যাক করতে ব্যবহার করে। এই নতুন ইমপ্লিমেন্টেশনটি মূলত র‍্যান্ডম এডিটের ক্ষেত্রে পারফরম্যান্স উন্নত করার জন্য ডিজাইন করা হয়েছে।

    নতুন SlotTable ব্যবহার করে দেখতে, ComposeRuntimeFlags.isLinkBufferComposerEnabled সক্রিয় করুন।

    আজই কোডিং শুরু করুন!

    Jetpack Compose-এ এতগুলো চমৎকার নতুন API এবং আরও অনেক কিছু আসতে থাকায়, Jetpack Compose-এ স্থানান্তরিত হওয়ার জন্য এর চেয়ে ভালো সময় আর হতে পারে না। বরাবরের মতোই, আমরা আপনার মতামত এবং ফিচার অনুরোধকে গুরুত্ব দিই (বিশেষ করে @Experimental ফিচারগুলোর উপর, যেগুলো এখনও তৈরি হচ্ছে) — অনুগ্রহ করে সেগুলো এখানে জমা দিন। হ্যাপি কম্পোজিং!

      লিখেছেন:
      পড়তে থাকুন
      ,
      পণ্যের খবর

      Jetpack Compose-এর এপ্রিল '২৬ সংস্করণে নতুন কী আছে

      পড়তে ৬ মিনিট
      মেঘান মেহতার প্রোফাইল দেখুন
      Meghan Mehta ডেভেলপার অ্যাডভোকেট, অ্যান্ড্রয়েড

      আজ, Jetpack Compose-এর এপ্রিল '২৬ রিলিজটি স্থিতিশীল হয়েছে। এই রিলিজে রয়েছে কোর কম্পোজ মডিউলের ১.১১ সংস্করণ (সম্পূর্ণ BOM ম্যাপিং দেখুন), শেয়ার্ড এলিমেন্ট ডিবাগ টুল, ট্র্যাকপ্যাড ইভেন্ট এবং আরও অনেক কিছু। এছাড়াও আমাদের কয়েকটি পরীক্ষামূলক API রয়েছে, যেগুলো আপনারা ব্যবহার করে দেখুন এবং সেগুলোর উপর আমাদের মতামত জানান।

      আজকের রিলিজটি ব্যবহার করতে, আপনার Compose BOM সংস্করণটি আপগ্রেড করে নিম্নোক্ত সংস্করণে নিয়ে যান:

      implementation(platform("androidx.compose:compose-bom:2026.04.01"))

      Compose 1.11.0-এর পরিবর্তনসমূহ

      টেস্টে কো-রুটিন এক্সিকিউশন

      Compose যেভাবে টেস্ট টাইমিং পরিচালনা করে, তাতে আমরা একটি বড় আপডেট আনছি। Compose 1.10-এ ঘোষিত অপ্ট-ইন পিরিয়ডের পর, v2 টেস্টিং API-গুলো এখন ডিফল্ট হিসেবে ব্যবহৃত হবে এবং v1 API-গুলোকে ডেপ্রিকেটেড করা হয়েছে। মূল পরিবর্তনটি হলো ডিফল্ট টেস্ট ডিসপ্যাচারের পরিবর্তন। যেখানে v1 API-গুলো UnconfinedTestDispatcher এর উপর নির্ভর করত, যা কো-রুটিনগুলোকে তাৎক্ষণিকভাবে এক্সিকিউট করত, সেখানে v2 API-গুলো StandardTestDispatcher ব্যবহার করে। এর মানে হলো, আপনার টেস্টে যখন কোনো কো-রুটিন চালু করা হয়, তখন সেটি এখন কিউ-তে জমা হয় এবং ভার্চুয়াল ক্লক এগিয়ে না যাওয়া পর্যন্ত এক্সিকিউট হয় না।

      এটি প্রোডাকশন পরিস্থিতিকে আরও ভালোভাবে অনুকরণ করে, কার্যকরভাবে রেস কন্ডিশনগুলো দূর করে এবং আপনার টেস্ট স্যুটকে উল্লেখযোগ্যভাবে আরও শক্তিশালী ও কম ত্রুটিপূর্ণ করে তোলে।

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

      শেয়ার করা উপাদানের উন্নতি এবং অ্যানিমেশন টুলিং

      আমরা শেয়ার্ড এলিমেন্ট এবং Modifier.animatedBounds এর জন্য কিছু দরকারি ভিজ্যুয়াল ডিবাগিং টুলও যুক্ত করেছি। এখন আপনি আড়ালে ঠিক কী ঘটছে তা দেখতে পারবেন—যেমন টার্গেট বাউন্ডস, অ্যানিমেশন ট্র্যাজেক্টরি এবং কতগুলো ম্যাচ পাওয়া গেছে—যার ফলে কোনো ট্রানজিশন কেন প্রত্যাশা অনুযায়ী কাজ করছে না, তা খুঁজে বের করা অনেক সহজ হয়ে যায়। নতুন টুলিং ব্যবহার করতে, আপনার SharedTransitionLayout-কে LookaheadAnimationVisualDebugging কম্পোজেবল দিয়ে ঘিরে দিন।

      LookaheadAnimationVisualDebugging(
          overlayColor = Color(0x4AE91E63),
          isEnabled = true,
          multipleMatchesColor = Color.Green,
          isShowKeylabelEnabled = false,
          unmatchedElementColor = Color.Red,
      ) {
          SharedTransitionLayout {
              CompositionLocalProvider(
                  LocalSharedTransitionScope provides this,
              ) {
                  // your content
              }
          }
      }

      ট্র্যাকপ্যাড ইভেন্টগুলি

      আমরা ল্যাপটপের বিল্ট-ইন ট্র্যাকপ্যাড, ট্যাবলেটের জন্য সংযুক্তযোগ্য ট্র্যাকপ্যাড, বা এক্সটার্নাল/ভার্চুয়াল ট্র্যাকপ্যাডের মতো ট্র্যাকপ্যাডগুলির জন্য Compose সাপোর্টকে নতুন করে সাজিয়েছি। বেসিক ট্র্যাকপ্যাড ইভেন্টগুলিকে এখন থেকে সাধারণত PointerType.Mouse ইভেন্ট হিসাবে বিবেচনা করা হবে, যা মাউস এবং ট্র্যাকপ্যাডের আচরণকে ব্যবহারকারীর প্রত্যাশার সাথে আরও ভালোভাবে মেলানোর জন্য সমন্বয় করে। পূর্বে, এই ট্র্যাকপ্যাড ইভেন্টগুলিকে PointerType.Touch এর নকল টাচস্ক্রিন আঙুল হিসাবে ব্যাখ্যা করা হতো, যা ব্যবহারকারীদের জন্য বিভ্রান্তিকর অভিজ্ঞতা তৈরি করত। উদাহরণস্বরূপ, ট্র্যাকপ্যাড দিয়ে ক্লিক এবং ড্র্যাগ করলে সিলেক্ট হওয়ার পরিবর্তে স্ক্রল হয়ে যেত। Compose-এর সর্বশেষ সংস্করণে এই ইভেন্টগুলির পয়েন্টার টাইপ পরিবর্তন করার ফলে, ট্র্যাকপ্যাড দিয়ে ক্লিক এবং ড্র্যাগ করলে আর স্ক্রল হবে না।

      আমরা এপিআই ৩৪ (API 34) থেকে প্ল্যাটফর্ম দ্বারা স্বীকৃত আরও জটিল ট্র্যাকপ্যাড জেসচারগুলির জন্য সমর্থনও যুক্ত করেছি, যার মধ্যে দুই আঙুলের সোয়াইপ এবং পিঞ্চ অন্তর্ভুক্ত। ট্র্যাকপ্যাডের সাথে আরও ভালো আচরণের জন্য এই জেসচারগুলি Modifier.scrollable এবং Modifier.transformable এর মতো কম্পোনেন্ট দ্বারা স্বয়ংক্রিয়ভাবে স্বীকৃত হয়।

      এই পরিবর্তনগুলো বিল্ট-ইন কম্পোনেন্ট জুড়ে ট্র্যাকপ্যাডের কার্যকারিতা উন্নত করে, যার মধ্যে রয়েছে অপ্রয়োজনীয় টাচ স্লপ অপসারণ, আরও স্বজ্ঞাত ড্র্যাগ-অ্যান্ড-ড্রপ স্টার্টিং জেসচার, টেক্সট ফিল্ডে ডাবল-ক্লিক ও ট্রিপল-ক্লিক সিলেকশন এবং টেক্সট ফিল্ডে ডেস্কটপ-স্টাইলের কনটেক্সট মেনু।

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

      beforeAndAfter.webp

      কম্পোজিশন হোস্ট ডিফল্ট (কম্পোজ রানটাইম)

      আমরা সরাসরি কম্পোজ-রানটাইমের মাধ্যমে হোস্ট-স্তরের পরিষেবা সরবরাহ করার জন্য HostDefaultProvider , LocalHostDefaultProvider , HostDefaultKey এবং ViewTreeHostDefaultKey চালু করেছি। এর ফলে লাইব্রেরিগুলোকে লুকআপের জন্য compose-ui উপর নির্ভর করতে হয় না, যা কোটলিন মাল্টিপ্ল্যাটফর্মকে আরও ভালোভাবে সমর্থন করে। এই মানগুলোকে কম্পোজিশন ট্রির সাথে লিঙ্ক করতে, লাইব্রেরির লেখকরা compositionLocalWithHostDefaultOf ব্যবহার করে একটি CompositionLocal তৈরি করতে পারেন, যা হোস্ট থেকে ডিফল্টগুলো রিজলভ করে।

      প্রিভিউ র‍্যাপার

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

      PreviewWrapperProvider ইন্টারফেসটি ইমপ্লিমেন্ট করে এবং নতুন @PreviewWrapper অ্যানোটেশনটি প্রয়োগ করার মাধ্যমে, আপনি সহজেই কাস্টম লজিক যুক্ত করতে পারেন, যেমন একটি নির্দিষ্ট Theme প্রয়োগ করা। এই অ্যানোটেশনটি @Composable এবং @Preview বা @MultiPreview দিয়ে অ্যানোটেটেড কোনো ফাংশনে প্রয়োগ করা যায়, যা একটি জেনেরিক ও সহজে ব্যবহারযোগ্য সমাধান প্রদান করে, যা বিভিন্ন প্রিভিউ ফিচারে কাজ করে এবং পুনরাবৃত্তিমূলক কোড উল্লেখযোগ্যভাবে হ্রাস করে।

      class ThemeWrapper: PreviewWrapperProvider {
          @Composable
          override fun Wrap(content: @Composable (() -> Unit)) {
              JetsnackTheme {
                  content()
              }
          }
      }
      
      
      @PreviewWrapper(ThemeWrapper::class)
      @Preview
      @Composable
      private fun ButtonPreview() {
          // JetsnackTheme in effect
          Button(onClick = {}) {
              Text(text = "Demo")
          }
      }

      অবচয় এবং অপসারণ

      • Compose 1.10 ব্লগ পোস্টে ঘোষিত ঘোষণা অনুযায়ী, আমরা Modifier.onFirstVisible() বাতিল করছি। এর নামটি প্রায়শই ভুল ধারণার জন্ম দিত, বিশেষ করে লেজি লেআউটের ক্ষেত্রে, যেখানে স্ক্রোল করার সময় এটি একাধিকবার ট্রিগার হতো। আমরা Modifier.onVisibilityChanged() ব্যবহার করার পরামর্শ দিচ্ছি, যা আপনার নির্দিষ্ট ব্যবহারের প্রয়োজন অনুযায়ী ভিজিবিলিটি স্টেটগুলোকে আরও নির্ভুলভাবে ম্যানুয়ালি ট্র্যাক করার সুযোগ দেয়।
      • ComposeFoundationFlags.isTextFieldDpadNavigationEnabled ফ্ল্যাগটি সরিয়ে দেওয়া হয়েছে, কারণ এখন TextFields জন্য ডি-প্যাড নেভিগেশন ডিফল্টরূপে সর্বদা সক্রিয় থাকে। নতুন এই আচরণটি নিশ্চিত করে যে, গেমপ্যাড বা টিভি রিমোট থেকে আসা ডি-প্যাড ইভেন্টগুলো প্রথমে কার্সারকে নির্দিষ্ট দিকে চালিত করবে। কার্সারটি টেক্সটের শেষে পৌঁছালেই কেবল ফোকাস অন্য কোনো এলিমেন্টে যেতে পারবে।

      আসন্ন এপিআই

      আসন্ন Compose 1.12.0 রিলিজে, compileSdk compileSdk 37 -এ আপগ্রেড করা হবে এবং এর সাথে AGP 9 যুক্ত হবে। Compose-এর উপর নির্ভরশীল সমস্ত অ্যাপ এবং লাইব্রেরিও এই রিকোয়ারমেন্টটি গ্রহণ করবে। আমরা সর্বশেষ প্রকাশিত সংস্করণগুলির সাথে আপ-টু-ডেট থাকার পরামর্শ দিই, কারণ Compose অ্যান্ড্রয়েডের সর্বশেষ ফিচারগুলিতে অ্যাক্সেস দেওয়ার জন্য দ্রুত নতুন compileSdks গ্রহণ করার লক্ষ্য রাখে। বিভিন্ন API লেভেলের জন্য AGP-এর কোন সংস্করণটি সমর্থিত, সে সম্পর্কে আরও তথ্যের জন্য এখানে ডকুমেন্টেশনটি অবশ্যই দেখে নিন।

      Compose 1.11.0-এ, নিম্নলিখিত API-গুলো @Experimental হিসেবে চালু করা হয়েছে, এবং আপনারা আপনাদের অ্যাপে এগুলো ব্যবহার করে দেখার পর আপনাদের মতামত জানানোর জন্য আমরা উন্মুখ হয়ে আছি। উল্লেখ্য যে, @Experimental APIs প্রাথমিক মূল্যায়ন ও মতামতের জন্য প্রদান করা হয়েছে এবং ভবিষ্যতের সংস্করণগুলোতে এগুলোতে উল্লেখযোগ্য পরিবর্তন আনা হতে পারে বা এগুলো সরিয়েও ফেলা হতে পারে।

      শৈলী (পরীক্ষামূলক)

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

      প্রেস করা অবস্থার স্টাইল ব্যাকগ্রাউন্ড ওভাররাইড করার একটি সাধারণ উদাহরণ:

      @Composable
      fun LoginButton(modifier: Modifier = Modifier) {
          Button(
              onClick = {
                  // Login logic
              },
              modifier = modifier,
              style = {
                  background(
                      Brush.linearGradient(
                          listOf(lightPurple, lightBlue)
                      )
                  )
                  width(75.dp)
                  height(50.dp)
                  textAlign(TextAlign.Center)
                  externalPadding(16.dp)
      
                  pressed {
                      background(
                          Brush.linearGradient(
                              listOf(Color.Magenta, Color.Red)
                          )
                      )
                  }
              }
          ){
              Text(
                  text = "Login",
              )
          }
      }
      স্টাইলস.ওয়েবপি

      ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

      মিডিয়া কোয়েরি (পরীক্ষামূলক)

      নতুন mediaQuery API আপনার UI-কে তার পরিবেশের সাথে খাপ খাইয়ে নেওয়ার জন্য একটি ডিক্লারেটিভ এবং পারফরম্যান্ট উপায় প্রদান করে। এটি একটি UiMediaScope মধ্যে জটিল তথ্য পুনরুদ্ধারকে সহজ শর্তে রূপান্তরিত করে, যা নিশ্চিত করে যে পুনর্গঠন কেবল প্রয়োজনের সময়ই ঘটবে।

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

      @Composable
      fun isTabletopPosture(
          context: Context = LocalContext.current
      ): Boolean {
          val windowLayoutInfo by
              WindowInfoTracker
                  .getOrCreate(context)
                  .windowLayoutInfo(context)
                  .collectAsStateWithLifecycle(null)
      
          return windowLayoutInfo.displayFeatures.any { displayFeature ->
              displayFeature is FoldingFeature &&
                  displayFeature.state == FoldingFeature.State.HALF_OPENED &&
                  displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
          }
      }
      
      @Composable
      fun VideoPlayer() {
          if(isTabletopPosture()) {
              TabletopLayout()
          } else {
              FlatLayout()
          }
      }

      এখন, UIMediaQuery ব্যবহার করে, আপনি mediaQuery সিনট্যাক্স যোগ করার মাধ্যমে ডিভাইসের বৈশিষ্ট্যগুলো জানতে পারবেন, যেমন ডিভাইসটি টেবিলটপ মোডে আছে কি না।

      @OptIn(ExperimentalMediaQueryApi::class)
      @Composable
      fun VideoPlayer() {
          if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
              TabletopLayout()
          } else {
              FlatLayout()
          }
      }

      ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

      গ্রিড (পরীক্ষামূলক)

      জেটপ্যাক কম্পোজে জটিল, দ্বি-মাত্রিক লেআউট তৈরির জন্য Grid একটি শক্তিশালী নতুন এপিআই। Row এবং Column রৈখিক ডিজাইনের জন্য চমৎকার হলেও, Grid আপনাকে স্ক্রলযোগ্য তালিকার বাড়তি ঝামেলা ছাড়াই স্ক্রিন-স্তরের আর্কিটেকচার এবং জটিল কম্পোনেন্টের জন্য প্রয়োজনীয় কাঠামোগত নিয়ন্ত্রণ দেয়। Grid আপনাকে ট্র্যাক, গ্যাপ এবং সেল ব্যবহার করে আপনার লেআউট নির্ধারণ করার সুযোগ দেয় এবং সাথে Dp , পার্সেন্টেজ, ইন্ট্রিনসিক কন্টেন্ট সাইজ এবং নমনীয় "Fr" ইউনিটের মতো পরিচিত সাইজিং অপশনও প্রদান করে।

      @OptIn(ExperimentalGridApi::class)
      @Composable
      fun GridExample() {
          Grid(
              config = {
                  repeat(4) { column(0.25f) }
                  repeat(2) { row(0.5f) }
                  gap(16.dp)
              }
          ) {
              Card1(modifier = Modifier.gridItem(rowSpan = 2)
              Card2(modifier = Modifier.gridItem(colmnSpan = 3)
              Card3(modifier = Modifier.gridItem(columnSpan = 2)
              Card4()
          }
      }

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

      Grid.gif

      ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

      ফ্লেক্সবক্স (পরীক্ষামূলক)

      FlexBox হলো উচ্চ পারফরম্যান্স ও অভিযোজনযোগ্য UI-এর জন্য ডিজাইন করা একটি লেআউট কন্টেইনার। এটি কন্টেইনারের উপলব্ধ আকারের উপর ভিত্তি করে আইটেমের আকার এবং স্থান বণ্টন পরিচালনা করে। এটি আইটেম র‍্যাপিং ( wrap ) এবং মাল্টি-অ্যাক্সিস অ্যালাইনমেন্টের ( justifyContent, alignItems, alignContent ) মতো জটিল কাজগুলো সামলায়। এটি আইটেমগুলোকে কন্টেইনার পূর্ণ করার জন্য বড় ( grow ) বা ছোট ( shrink ) হতে দেয়।

      @OptIn(ExperimentalFlexBoxApi::class)
      fun FlexBoxWrapping(){
          FlexBox(
              config = {
                  wrap(FlexWrap.Wrap)
                  gap(8.dp)
              }
          ) {
              RedRoundedBox()
              BlueRoundedBox()
              GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
              OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
              PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
          }
      }
      AnimationGif.gif

      ডকুমেন্টেশনটি দেখুন এবং যেকোনো বাগ এখানে রিপোর্ট করুন।

      নতুন স্লটটেবিল বাস্তবায়ন (পরীক্ষামূলক)

      আমরা SlotTable এর একটি নতুন ইমপ্লিমেন্টেশন চালু করেছি, যা এই রিলিজে ডিফল্টরূপে নিষ্ক্রিয় রয়েছে। SlotTable হলো একটি অভ্যন্তরীণ ডেটা স্ট্রাকচার যা Compose রানটাইম আপনার কম্পোজিশন হায়ারার্কির অবস্থা ট্র্যাক করতে, ইনভ্যালিডেশন/রিকম্পোজিশন ট্র্যাক করতে, মনে রাখা মান সংরক্ষণ করতে এবং রানটাইমে কম্পোজিশনের সমস্ত মেটাডেটা ট্র্যাক করতে ব্যবহার করে। এই নতুন ইমপ্লিমেন্টেশনটি মূলত র‍্যান্ডম এডিটের ক্ষেত্রে পারফরম্যান্স উন্নত করার জন্য ডিজাইন করা হয়েছে।

      নতুন SlotTable ব্যবহার করে দেখতে, ComposeRuntimeFlags.isLinkBufferComposerEnabled সক্রিয় করুন।

      আজই কোডিং শুরু করুন!

      Jetpack Compose-এ এতগুলো চমৎকার নতুন API এবং আরও অনেক কিছু আসতে থাকায়, Jetpack Compose-এ স্থানান্তরিত হওয়ার জন্য এর চেয়ে ভালো সময় আর হতে পারে না। বরাবরের মতোই, আমরা আপনার মতামত এবং ফিচার অনুরোধকে গুরুত্ব দিই (বিশেষ করে @Experimental ফিচারগুলোর উপর, যেগুলো এখনও তৈরি হচ্ছে) — অনুগ্রহ করে সেগুলো এখানে জমা দিন। হ্যাপি কম্পোজিং!

        লিখেছেন:
        পড়তে থাকুন
        ,
        পণ্যের খবর

        Jetpack Compose-এর এপ্রিল '২৬ সংস্করণে নতুন কী আছে

        পড়তে ৬ মিনিট
        মেঘান মেহতার প্রোফাইল দেখুন
        Meghan Mehta ডেভেলপার অ্যাডভোকেট, অ্যান্ড্রয়েড

        আজ, Jetpack Compose-এর এপ্রিল '২৬ রিলিজটি স্থিতিশীল হয়েছে। এই রিলিজে রয়েছে কোর কম্পোজ মডিউলের ১.১১ সংস্করণ (সম্পূর্ণ BOM ম্যাপিং দেখুন), শেয়ার্ড এলিমেন্ট ডিবাগ টুল, ট্র্যাকপ্যাড ইভেন্ট এবং আরও অনেক কিছু। এছাড়াও আমাদের কয়েকটি পরীক্ষামূলক API রয়েছে, যেগুলো আপনারা ব্যবহার করে দেখুন এবং সেগুলোর উপর আমাদের মতামত জানান।

        আজকের রিলিজটি ব্যবহার করতে, আপনার Compose BOM সংস্করণটি আপগ্রেড করে নিম্নোক্ত সংস্করণে নিয়ে যান:

        implementation(platform("androidx.compose:compose-bom:2026.04.01"))

        Compose 1.11.0-এর পরিবর্তনসমূহ

        টেস্টে কো-রুটিন এক্সিকিউশন

        We're introducing a major update to how Compose handles test timing. Following the opt-in period announced in Compose 1.10, the v2 testing APIs are now the default, and the v1 APIs have been deprecated. The key change is a shift in the default test dispatcher. While the v1 APIs relied on the UnconfinedTestDispatcher , which executed coroutines immediately, the v2 APIs use the StandardTestDispatcher . This means that when a coroutine is launched in your tests, it is now queued and does not execute until the virtual clock is advanced.

        This better mimics production conditions, effectively flushing out race conditions and making your test suite significantly more robust and less flaky.

        To ensure your tests align with standard coroutine behavior and to avoid future compatibility issues, we strongly recommend migrating your test suite. Check out our comprehensive migration guide for API mappings and common fixes.

        Shared element improvements and animation tooling

        We've also added some handy visual debugging tools for shared elements and Modifier.animatedBounds . You can now see exactly what's happening under the hood—like target bounds, animation trajectories, and how many matches are found—making it much easier to spot why a transition might not be behaving as expected. To use the new tooling, simply surround your SharedTransitionLayout with the LookaheadAnimationVisualDebugging composable.

        LookaheadAnimationVisualDebugging(
            overlayColor = Color(0x4AE91E63),
            isEnabled = true,
            multipleMatchesColor = Color.Green,
            isShowKeylabelEnabled = false,
            unmatchedElementColor = Color.Red,
        ) {
            SharedTransitionLayout {
                CompositionLocalProvider(
                    LocalSharedTransitionScope provides this,
                ) {
                    // your content
                }
            }
        }

        Trackpad events

        We've revamped Compose support for trackpads, like built-in laptop trackpads, attachable trackpads for tablets, or external/virtual trackpads. Basic trackpad events will now generally be considered PointerType.Mouse events, aligning mouse and trackpad behavior to better match user expectations. Previously, these trackpad events were interpreted as fake touchscreen fingers of PointerType.Touch , which led to confusing user experiences. For example, clicking and dragging with a trackpad would scroll instead of selecting. By changing the pointer type these events have in the latest release of Compose, clicking and dragging with a trackpad will no longer scroll.

        We also added support for more complicated trackpad gestures as recognized by the platform since API 34, including two finger swipes and pinches . These gestures are automatically recognized by components like Modifier.scrollable and Modifier.transformable to have better behavior with trackpads.

        These changes improve behavior for trackpads across built-in components, with redundant touch slop removed, a more intuitive drag-and-drop starting gesture, double-click and triple-click selection in text fields, and desktop-styled context menus in text fields.

        To test trackpad behavior, there are new testing APIs with performTrackpadInput , which allow validating the behavior of your apps when being used with a trackpad. If you have custom gesture detectors, validate behavior across input types, including touchscreens, mice, trackpads, and styluses, and ensure support for mouse scroll wheels and trackpad gestures.

        beforeAndAfter.webp

        Composition host defaults (Compose runtime)

        We introduced HostDefaultProvider , LocalHostDefaultProvider , HostDefaultKey , and ViewTreeHostDefaultKey to supply host-level services directly through compose-runtime. This removes the need for libraries to depend on compose-ui for lookups, better supporting Kotlin Multiplatform. To link these values to the composition tree, library authors can use compositionLocalWithHostDefaultOf to create a CompositionLocal that resolves defaults from the host.

        Preview wrappers

        Android Studio custom previews is a new feature that allows you to define exactly how the contents of a Compose preview are displayed.

        By implementing the PreviewWrapperProvider interface and applying the new @PreviewWrapper annotation, you can easily inject custom logic, such as applying a specific Theme . The annotation can be applied to a function annotated with @Composable and @Preview or @MultiPreview , offering a generic, easy-to-use solution that works across preview features and significantly reduces repetitive code.

        class ThemeWrapper: PreviewWrapperProvider {
            @Composable
            override fun Wrap(content: @Composable (() -> Unit)) {
                JetsnackTheme {
                    content()
                }
            }
        }
        
        
        @PreviewWrapper(ThemeWrapper::class)
        @Preview
        @Composable
        private fun ButtonPreview() {
            // JetsnackTheme in effect
            Button(onClick = {}) {
                Text(text = "Demo")
            }
        }

        Deprecations and removals

        • As announced in the Compose 1.10 blog post , we're deprecating Modifier.onFirstVisible() . Its name often led to misconceptions, particularly within lazy layouts, where it would trigger multiple times during scrolling. We recommend migrating to Modifier.onVisibilityChanged() , which allows for more precise manual tracking of visibility states tailored to your specific use case requirements.
        • The ComposeFoundationFlags.isTextFieldDpadNavigationEnabled flag was removed because D-pad navigation for TextFields is now always enabled by default. The new behavior ensures that the D-pad events from a gamepad or a TV remote first move the cursor in the given direction. The focus can move to another element only when the cursor reaches the end of the text.

        Upcoming APIs

        In the upcoming Compose 1.12.0 release, the compileSdk will be upgraded to compileSdk 37 , with AGP 9 and all apps and libraries that depend on Compose inheriting this requirement. We recommend keeping up to date with the latest released versions, as Compose aims to promptly adopt new compileSdks to provide access to the latest Android features. Be sure to check out the documentation here for more information on which version of AGP is supported for different API levels.

        In Compose 1.11.0, the following APIs are introduced as @Experimental , and we look forward to hearing your feedback as you explore them in your apps. Note that @Experimental APIs are provided for early evaluation and feedback and may undergo significant changes or removal in future releases.

        Styles (Experimental)

        We are introducing a new experimental foundation API for styling . The Style API is a new paradigm for customizing visual elements of components, which has traditionally been performed with modifiers. It is designed to unlock deeper, easier customization by exposing a standard set of styleable properties with simple state-based styling and animated transitions. With this new API, we're already seeing promising performance benefits . We plan to adopt Styles in Material components once the Style API stabilizes.

        A basic example of overriding a pressed state style background:

        @Composable
        fun LoginButton(modifier: Modifier = Modifier) {
            Button(
                onClick = {
                    // Login logic
                },
                modifier = modifier,
                style = {
                    background(
                        Brush.linearGradient(
                            listOf(lightPurple, lightBlue)
                        )
                    )
                    width(75.dp)
                    height(50.dp)
                    textAlign(TextAlign.Center)
                    externalPadding(16.dp)
        
                    pressed {
                        background(
                            Brush.linearGradient(
                                listOf(Color.Magenta, Color.Red)
                            )
                        )
                    }
                }
            ){
                Text(
                    text = "Login",
                )
            }
        }
        styles.webp

        Check out the documentation and file any bugs here .

        MediaQuery (Experimental)

        The new mediaQuery API provides a declarative and performant way to adapt your UI to its environment. It abstracts complex information retrieval into simple conditions within a UiMediaScope , ensuring recomposition only happens when needed.

        With support for a wide range of environmental signals—from device capabilities like keyboard types and pointer precision, to contextual states like window size and posture—you can build deeply responsive experiences. Performance is baked in with derivedMediaQuery to handle high-frequency updates, while the ability to override scopes makes testing and previews seamless across hardware configurations. Previously, to get access to certain device properties — like if a device was in tabletop mode — you'd need to write a lot of boilerplate to do so:

        @Composable
        fun isTabletopPosture(
            context: Context = LocalContext.current
        ): Boolean {
            val windowLayoutInfo by
                WindowInfoTracker
                    .getOrCreate(context)
                    .windowLayoutInfo(context)
                    .collectAsStateWithLifecycle(null)
        
            return windowLayoutInfo.displayFeatures.any { displayFeature ->
                displayFeature is FoldingFeature &&
                    displayFeature.state == FoldingFeature.State.HALF_OPENED &&
                    displayFeature.orientation == FoldingFeature.Orientation.HORIZONTAL
            }
        }
        
        @Composable
        fun VideoPlayer() {
            if(isTabletopPosture()) {
                TabletopLayout()
            } else {
                FlatLayout()
            }
        }

        Now, with UIMediaQuery , you can add the mediaQuery syntax to query device properties, such as if a device is in tabletop mode:

        @OptIn(ExperimentalMediaQueryApi::class)
        @Composable
        fun VideoPlayer() {
            if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
                TabletopLayout()
            } else {
                FlatLayout()
            }
        }

        Check out the documentation and file any bugs here .

        Grid (Experimental)

        Grid is a powerful new API for building complex, two-dimensional layouts in Jetpack Compose. While Row and Column are great for linear designs, Grid gives you the structural control needed for screen-level architecture and intricate components without the overhead of a scrollable list. Grid allows you to define your layout using tracks, gaps, and cells, offering familiar sizing options like Dp , percentages, intrinsic content sizes, and flexible "Fr" units.

        @OptIn(ExperimentalGridApi::class)
        @Composable
        fun GridExample() {
            Grid(
                config = {
                    repeat(4) { column(0.25f) }
                    repeat(2) { row(0.5f) }
                    gap(16.dp)
                }
            ) {
                Card1(modifier = Modifier.gridItem(rowSpan = 2)
                Card2(modifier = Modifier.gridItem(colmnSpan = 3)
                Card3(modifier = Modifier.gridItem(columnSpan = 2)
                Card4()
            }
        }

        You can place items automatically or explicitly span them across multiple rows and columns for precision. Best of all, it's highly adaptive—you can dynamically reconfigure your grid tracks and spans to respond to device states like tabletop mode or orientation changes, ensuring your UI looks great across form factors.

        Grid.gif

        Check out the documentation and file any bugs here .

        FlexBox (Experimental)

        FlexBox is a layout container designed for high performance, adaptive UIs. It manages item sizing and space distribution based on available container dimensions. It handles complex tasks like wrapping ( wrap ) and multi-axis alignment of items ( justifyContent, alignItems, alignContent ). It allows items to grow ( grow ) or shrink ( shrink ) to fill the container.

        @OptIn(ExperimentalFlexBoxApi::class)
        fun FlexBoxWrapping(){
            FlexBox(
                config = {
                    wrap(FlexWrap.Wrap)
                    gap(8.dp)
                }
            ) {
                RedRoundedBox()
                BlueRoundedBox()
                GreenRoundedBox(modifier = Modifier.width(350.dp).flex { grow(1.0f) })
                OrangeRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.7f) })
                PinkRoundedBox(modifier = Modifier.width(200.dp).flex { grow(0.3f) })
            }
        }
        AnimationGif.gif

        Check out the documentation and file any bugs here .

        New SlotTable implementation (Experimental)

        We've introduced a new implementation of the SlotTable , which is disabled by default in this release. SlotTable is the internal data structure that the Compose runtime uses to track the state of your composition hierarchy, track invalidations/recompositions, store remembered values, and track all metadata of the composition at runtime. This new implementation is designed to improve performance, primarily around random edits.

        To try the new SlotTable , enable ComposeRuntimeFlags.isLinkBufferComposerEnabled .

        Start coding today!

        With so many exciting new APIs in Jetpack Compose, and many more coming up, it's never been a better time to migrate to Jetpack Compose . As always, we value your feedback and feature requests (especially on @Experimental features that are still baking) — please file them here . Happy composing!

          লিখেছেন:
          পড়তে থাকুন