সংশোধক রচনা করুন

সংশোধক আপনাকে একটি কম্পোজেবল সাজাতে বা বৃদ্ধি করতে দেয়। সংশোধক আপনাকে এই ধরণের জিনিসগুলি করতে দেয়:

  • কম্পোজেবলের আকার, বিন্যাস, আচরণ এবং চেহারা পরিবর্তন করুন
  • তথ্য যোগ করুন, যেমন অ্যাক্সেসিবিলিটি লেবেল
  • ব্যবহারকারীর ইনপুট প্রক্রিয়া করুন
  • উচ্চ-স্তরের মিথস্ক্রিয়া যোগ করুন, যেমন একটি উপাদান ক্লিকযোগ্য, স্ক্রোলযোগ্য, টেনে আনা বা জুমযোগ্য করা

সংশোধকগুলি স্ট্যান্ডার্ড কোটলিন অবজেক্ট। Modifier শ্রেণীর ফাংশনগুলির একটিতে কল করে একটি সংশোধক তৈরি করুন:

@Composable
private fun Greeting(name: String) {
    Column(modifier = Modifier.padding(24.dp)) {
        Text(text = "Hello,")
        Text(text = name)
    }
}

একটি রঙিন পটভূমিতে পাঠ্যের দুটি লাইন, পাঠ্যের চারপাশে প্যাডিং সহ।

আপনি তাদের রচনা করতে এই ফাংশনগুলিকে একসাথে চেইন করতে পারেন:

@Composable
private fun Greeting(name: String) {
    Column(
        modifier = Modifier
            .padding(24.dp)
            .fillMaxWidth()
    ) {
        Text(text = "Hello,")
        Text(text = name)
    }
}

পাঠ্যের পিছনে রঙিন পটভূমি এখন ডিভাইসের সম্পূর্ণ প্রস্থকে প্রসারিত করে।

উপরের কোডে, একসাথে ব্যবহৃত বিভিন্ন মডিফায়ার ফাংশন লক্ষ্য করুন।

  • padding একটি উপাদানের চারপাশে স্থান রাখে।
  • fillMaxWidth তার অভিভাবক থেকে প্রদত্ত সর্বাধিক প্রস্থ কম্পোজযোগ্য পূরণ করে।

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

সংশোধক বিষয়ের ক্রম

মডিফায়ার ফাংশনের ক্রম উল্লেখযোগ্য । যেহেতু প্রতিটি ফাংশন পূর্ববর্তী ফাংশন দ্বারা প্রত্যাবর্তিত Modifier পরিবর্তন করে, তাই ক্রম চূড়ান্ত ফলাফলকে প্রভাবিত করে। এর একটি উদাহরণ দেখা যাক:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

প্রান্তের চারপাশে প্যাডিং সহ সমগ্র এলাকা ক্লিকে সাড়া দেয়

উপরের কোডে আশেপাশের প্যাডিং সহ পুরো এলাকাটি ক্লিকযোগ্য, কারণ clickable মডিফায়ারের পরে padding মডিফায়ার প্রয়োগ করা হয়েছে। যদি মডিফায়ার অর্ডার বিপরীত হয়, padding দ্বারা যোগ করা স্থান ব্যবহারকারীর ইনপুটে প্রতিক্রিয়া দেখায় না:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .padding(padding)
            .clickable(onClick = onClick)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

লেআউটের প্রান্তের চারপাশের প্যাডিং আর ক্লিকে সাড়া দেয় না

অন্তর্নির্মিত সংশোধক

জেটপ্যাক কম্পোজ বিল্ট-ইন সংশোধকগুলির একটি তালিকা প্রদান করে যা আপনাকে একটি কম্পোজেবল সাজাতে বা বৃদ্ধি করতে সহায়তা করে। এখানে কিছু সাধারণ সংশোধক রয়েছে যা আপনি আপনার লেআউটগুলি সামঞ্জস্য করতে ব্যবহার করবেন৷

padding এবং size

ডিফল্টরূপে, কম্পোজে প্রদত্ত লেআউটগুলি তাদের বাচ্চাদের মোড়ানো। যাইহোক, আপনি size পরিবর্তনকারী ব্যবহার করে একটি আকার সেট করতে পারেন:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(/*...*/)
        Column { /*...*/ }
    }
}

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

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.requiredSize(150.dp)
        )
        Column { /*...*/ }
    }
}

শিশুর চিত্র তার পিতামাতার কাছ থেকে আসা সীমাবদ্ধতার চেয়ে বড়

এই উদাহরণে, এমনকি প্যারেন্ট height 100.dp এ সেট করা থাকলেও, Image উচ্চতা হবে 150.dp , কারণ requiredSize মডিফায়ার অগ্রাধিকার নেয়।

আপনি যদি চান যে একটি চাইল্ড লেআউট পিতামাতার দ্বারা অনুমোদিত সমস্ত উপলব্ধ উচ্চতা পূরণ করতে, fillMaxHeight সংশোধক যোগ করুন (কম্পোজ এছাড়াও fillMaxSize এবং fillMaxWidth প্রদান করে):

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.fillMaxHeight()
        )
        Column { /*...*/ }
    }
}

ছবির উচ্চতা তার পিতামাতার মতোই বড়

একটি উপাদানের চারপাশে প্যাডিং যোগ করতে, একটি padding সংশোধক সেট করুন।

আপনি যদি একটি পাঠ্য বেসলাইনের উপরে প্যাডিং যুক্ত করতে চান যাতে আপনি লেআউটের শীর্ষ থেকে বেসলাইনে একটি নির্দিষ্ট দূরত্ব অর্জন করতে পারেন, তাহলে paddingFromBaseline সংশোধক ব্যবহার করুন:

@Composable
fun ArtistCard(artist: Artist) {
    Row(/*...*/) {
        Column {
            Text(
                text = artist.name,
                modifier = Modifier.paddingFromBaseline(top = 50.dp)
            )
            Text(artist.lastSeenOnline)
        }
    }
}

এর উপরে প্যাডিং সহ পাঠ্য

অফসেট

একটি লেআউটকে তার আসল অবস্থানের সাথে সম্পর্কিত করতে, offset মডিফায়ার যোগ করুন এবং অফসেটটিকে x এবং y অক্ষে সেট করুন। অফসেটগুলি ইতিবাচক এবং অ-ইতিবাচক হতে পারে। padding এবং offset মধ্যে পার্থক্য হল যে একটি কম্পোজেবলে একটি offset যোগ করলে এর পরিমাপ পরিবর্তন হয় না:

@Composable
fun ArtistCard(artist: Artist) {
    Row(/*...*/) {
        Column {
            Text(artist.name)
            Text(
                text = artist.lastSeenOnline,
                modifier = Modifier.offset(x = 4.dp)
            )
        }
    }
}

পাঠ্যটি এর মূল কন্টেইনারের ডানদিকে স্থানান্তরিত হয়েছে৷

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

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

রচনায় স্কোপ নিরাপত্তা

কম্পোজে, এমন কিছু সংশোধক রয়েছে যা শুধুমাত্র নির্দিষ্ট কম্পোজেবলের শিশুদের ক্ষেত্রে প্রয়োগ করা যেতে পারে। কম্পোজ কাস্টম স্কোপের মাধ্যমে এটি প্রয়োগ করে।

উদাহরণস্বরূপ, আপনি যদি Box আকারকে প্রভাবিত না করে একটি শিশুকে প্যারেন্ট Box মতো বড় করতে চান তবে matchParentSize মডিফায়ার ব্যবহার করুন৷ matchParentSize শুধুমাত্র BoxScope এ উপলব্ধ। অতএব, এটি শুধুমাত্র একটি Box পিতামাতার মধ্যে একটি শিশুর উপর ব্যবহার করা যেতে পারে।

স্কোপ নিরাপত্তা আপনাকে মডিফায়ার যোগ করা থেকে বাধা দেয় যা অন্য কম্পোজেবল এবং স্কোপে কাজ করবে না এবং ট্রায়াল এবং ত্রুটি থেকে সময় বাঁচায়।

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

matchParentSize ইন Box ম্যাচ করুন

উপরে উল্লিখিত হিসাবে, আপনি যদি Box আকারকে প্রভাবিত না করে একটি শিশুর বিন্যাসটি প্যারেন্ট Box মতো একই আকারের হতে চান তবে matchParentSize মডিফায়ার ব্যবহার করুন৷

মনে রাখবেন matchParentSize শুধুমাত্র একটি Box স্কোপের মধ্যে উপলব্ধ, যার অর্থ এটি শুধুমাত্র Box কম্পোজেবলের সরাসরি শিশুদের জন্য প্রযোজ্য।

নীচের উদাহরণে, চাইল্ড Spacer মাপ তার প্যারেন্ট Box থেকে নেয়, যা এই ক্ষেত্রে সবচেয়ে বড় বাচ্চাদের ArtistCard থেকে তার আকার নেয়।

@Composable
fun MatchParentSizeComposable() {
    Box {
        Spacer(
            Modifier
                .matchParentSize()
                .background(Color.LightGray)
        )
        ArtistCard()
    }
}

ধূসর পটভূমি তার ধারক ভর্তি

যদি matchParentSize এর পরিবর্তে fillMaxSize ব্যবহার করা হয়, তাহলে Spacer অভিভাবকের কাছে অনুমোদিত সমস্ত উপলব্ধ স্থান নিয়ে যাবে, যার ফলে অভিভাবক সমস্ত উপলব্ধ স্থান প্রসারিত করতে এবং পূরণ করতে পারে।

ধূসর পটভূমি স্ক্রীন ভরাট করে

Row এবং Column weight

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

একটি Row নেওয়া যাক যেখানে দুটি Box কম্পোজেবল রয়েছে। প্রথম বাক্সটি দ্বিতীয়টির weight দ্বিগুণ দেওয়া হয়েছে, তাই এটি প্রস্থের দ্বিগুণ দেওয়া হয়েছে। যেহেতু Row 210.dp প্রশস্ত, প্রথম Box 140.dp চওড়া এবং দ্বিতীয়টি 70.dp :

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Image(
            /*...*/
            modifier = Modifier.weight(2f)
        )
        Column(
            modifier = Modifier.weight(1f)
        ) {
            /*...*/
        }
    }
}

ছবির প্রস্থ দ্বিগুণ পাঠ্য প্রস্থ

সংশোধক নিষ্কাশন এবং পুনরায় ব্যবহার

একাধিক সংশোধককে একটি কম্পোজেবল সাজাতে বা বাড়ানোর জন্য একসাথে চেইন করা যেতে পারে। এই চেইনটি Modifier ইন্টারফেসের মাধ্যমে তৈরি করা হয়েছে যা একক Modifier.Elements একটি অর্ডারকৃত, অপরিবর্তনীয় তালিকা উপস্থাপন করে।

প্রতিটি Modifier.Element একটি স্বতন্ত্র আচরণের প্রতিনিধিত্ব করে, যেমন লেআউট, অঙ্কন এবং গ্রাফিক্স আচরণ, সমস্ত অঙ্গভঙ্গি-সম্পর্কিত, ফোকাস এবং শব্দার্থবিদ্যা আচরণ, সেইসাথে ডিভাইস ইনপুট ইভেন্ট। তাদের ক্রমবিন্যাস বিষয়: সংশোধক উপাদানগুলি যা প্রথমে যোগ করা হয় তা প্রথমে প্রয়োগ করা হবে।

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

  • সংশোধকগুলির পুনরায় বরাদ্দকরণের পুনরাবৃত্তি হবে না যখন কম্পোজেবলগুলির জন্য পুনর্গঠন ঘটে যা তাদের ব্যবহার করে
  • সংশোধক চেইনগুলি সম্ভাব্যভাবে খুব দীর্ঘ এবং জটিল হতে পারে, তাই একটি চেইনের একই দৃষ্টান্ত পুনঃব্যবহার করা কাজের চাপ কমিয়ে দিতে পারে কম্পোজ রানটাইম তাদের তুলনা করার সময় যা করতে হবে
  • এই নিষ্কাশন কোডবেস জুড়ে কোড পরিচ্ছন্নতা, ধারাবাহিকতা এবং রক্ষণাবেক্ষণের প্রচার করে

সংশোধক পুনঃব্যবহারের জন্য সর্বোত্তম অনুশীলন

আপনার নিজস্ব Modifier চেইন তৈরি করুন এবং একাধিক সংমিশ্রণযোগ্য উপাদানগুলিতে পুনঃব্যবহার করতে সেগুলি বের করুন। শুধুমাত্র একটি সংশোধক সংরক্ষণ করা সম্পূর্ণরূপে সূক্ষ্ম, কারণ সেগুলি ডেটার মতো বস্তু:

val reusableModifier = Modifier
    .fillMaxWidth()
    .background(Color.Red)
    .padding(12.dp)

ঘন ঘন পরিবর্তিত অবস্থা পর্যবেক্ষণ করার সময় সংশোধকগুলি নিষ্কাশন এবং পুনরায় ব্যবহার করা

অ্যানিমেশন স্টেট বা scrollState মতো কম্পোজেবলের ভিতরে ঘন ঘন পরিবর্তনশীল অবস্থা পর্যবেক্ষণ করার সময়, উল্লেখযোগ্য পরিমাণে পুনর্গঠন করা যেতে পারে। এই ক্ষেত্রে, আপনার সংশোধকগুলি প্রতিটি পুনর্গঠনে এবং সম্ভাব্য প্রতিটি ফ্রেমের জন্য বরাদ্দ করা হবে:

@Composable
fun LoadingWheelAnimation() {
    val animatedState = animateFloatAsState(/*...*/)

    LoadingWheel(
        // Creation and allocation of this modifier will happen on every frame of the animation!
        modifier = Modifier
            .padding(12.dp)
            .background(Color.Gray),
        animatedState = animatedState
    )
}

পরিবর্তে, আপনি মডিফায়ারের একই উদাহরণ তৈরি, নিষ্কাশন এবং পুনঃব্যবহার করতে পারেন এবং এটিকে কম্পোজেবলে পাস করতে পারেন:

// Now, the allocation of the modifier happens here:
val reusableModifier = Modifier
    .padding(12.dp)
    .background(Color.Gray)

@Composable
fun LoadingWheelAnimation() {
    val animatedState = animateFloatAsState(/*...*/)

    LoadingWheel(
        // No allocation, as we're just reusing the same instance
        modifier = reusableModifier,
        animatedState = animatedState
    )
}

আনস্কোপড মডিফায়ার বের করা এবং পুনরায় ব্যবহার করা

সংশোধকগুলিকে একটি নির্দিষ্ট কম্পোজেবলে আনস্কোপ বা স্কোপ করা যেতে পারে। আনস্কোপড মডিফায়ারের ক্ষেত্রে, আপনি সহজ ভেরিয়েবল হিসাবে যেকোন কম্পোজেবলের বাইরে এগুলি সহজে বের করতে পারেন:

val reusableModifier = Modifier
    .fillMaxWidth()
    .background(Color.Red)
    .padding(12.dp)

@Composable
fun AuthorField() {
    HeaderText(
        // ...
        modifier = reusableModifier
    )
    SubtitleText(
        // ...
        modifier = reusableModifier
    )
}

অলস লেআউটগুলির সাথে মিলিত হলে এটি বিশেষত উপকারী হতে পারে। বেশিরভাগ ক্ষেত্রে, আপনি চাইবেন আপনার সমস্ত, সম্ভাব্য তাৎপর্যপূর্ণ, আইটেমের পরিমাণে একই সংশোধক থাকুক:

val reusableItemModifier = Modifier
    .padding(bottom = 12.dp)
    .size(216.dp)
    .clip(CircleShape)

@Composable
private fun AuthorList(authors: List<Author>) {
    LazyColumn {
        items(authors) {
            AsyncImage(
                // ...
                modifier = reusableItemModifier,
            )
        }
    }
}

স্কোপড মডিফায়ার বের করা এবং পুনরায় ব্যবহার করা

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

Column(/*...*/) {
    val reusableItemModifier = Modifier
        .padding(bottom = 12.dp)
        // Align Modifier.Element requires a ColumnScope
        .align(Alignment.CenterHorizontally)
        .weight(1f)
    Text1(
        modifier = reusableItemModifier,
        // ...
    )
    Text2(
        modifier = reusableItemModifier
        // ...
    )
    // ...
}

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

Column(modifier = Modifier.fillMaxWidth()) {
    // Weight modifier is scoped to the Column composable
    val reusableItemModifier = Modifier.weight(1f)

    // Weight will be properly assigned here since this Text is a direct child of Column
    Text1(
        modifier = reusableItemModifier
        // ...
    )

    Box {
        Text2(
            // Weight won't do anything here since the Text composable is not a direct child of Column
            modifier = reusableItemModifier
            // ...
        )
    }
}

নিষ্কাশিত মডিফায়ারের আরও চেইনিং

আপনি .then() ফাংশনটি কল করে আপনার এক্সট্র্যাক্ট করা মডিফায়ার চেইনকে আরও চেইন বা যুক্ত করতে পারেন:

val reusableModifier = Modifier
    .fillMaxWidth()
    .background(Color.Red)
    .padding(12.dp)

// Append to your reusableModifier
reusableModifier.clickable { /*...*/ }

// Append your reusableModifier
otherModifier.then(reusableModifier)

শুধু মনে রাখবেন যে পরিবর্তনকারীর ক্রম গুরুত্বপূর্ণ!

আরও জানুন

আমরা তাদের পরামিতি এবং সুযোগ সহ পরিবর্তকগুলির একটি সম্পূর্ণ তালিকা প্রদান করি৷

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

কাস্টম মডিফায়ার এবং কীভাবে সেগুলি তৈরি করতে হয় সে সম্পর্কে আরও তথ্যের জন্য, কাস্টম লেআউটের ডকুমেন্টেশনটি দেখুন - লেআউট মডিফায়ার ব্যবহার করে

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