রাজ্য এবং জেটপ্যাক রচনা

একটি অ্যাপ্লিকেশানের অবস্থা হল যেকোনো মান যা সময়ের সাথে সাথে পরিবর্তিত হতে পারে। এটি একটি খুব বিস্তৃত সংজ্ঞা এবং এটি একটি রুম ডাটাবেস থেকে শুরু করে একটি ক্লাসের একটি পরিবর্তনশীল পর্যন্ত সবকিছুকে অন্তর্ভুক্ত করে।

সমস্ত অ্যান্ড্রয়েড অ্যাপ ব্যবহারকারীর কাছে স্থিতি প্রদর্শন করে। অ্যান্ড্রয়েড অ্যাপে রাজ্যের কয়েকটি উদাহরণ:

  • একটি স্ন্যাকবার যা দেখায় কখন একটি নেটওয়ার্ক সংযোগ স্থাপন করা যায় না৷
  • একটি ব্লগ পোস্ট এবং সংশ্লিষ্ট মন্তব্য.
  • বোতামে রিপল অ্যানিমেশন যা একজন ব্যবহারকারী ক্লিক করলে প্লে হয়।
  • স্টিকার যা একজন ব্যবহারকারী একটি ছবির উপরে আঁকতে পারেন।

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

রাষ্ট্র এবং রচনা

রচনাটি ঘোষণামূলক এবং এটি আপডেট করার একমাত্র উপায় হল নতুন আর্গুমেন্টের সাথে একই কম্পোজযোগ্য কল করা। এই আর্গুমেন্ট হল UI রাজ্যের প্রতিনিধিত্ব। যে কোন সময় একটি রাষ্ট্র আপডেট করা হয় একটি পুনর্গঠন সঞ্চালিত হয়. ফলস্বরূপ, TextField মতো জিনিসগুলি স্বয়ংক্রিয়ভাবে আপডেট হয় না যেমন তারা অপরিহার্য XML ভিত্তিক ভিউতে করে। সেই অনুযায়ী আপডেট করার জন্য একটি কম্পোজেবলকে স্পষ্টভাবে নতুন অবস্থা বলতে হবে।

@Composable
private fun HelloContent() {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello!",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.bodyMedium
        )
        OutlinedTextField(
            value = "",
            onValueChange = { },
            label = { Text("Name") }
        )
    }
}

আপনি যদি এটি চালান এবং পাঠ্য প্রবেশ করার চেষ্টা করেন, আপনি দেখতে পাবেন যে কিছুই হবে না। এর কারণ TextField নিজেকে আপডেট করে না - এটি আপডেট হয় যখন এর value প্যারামিটার পরিবর্তন হয়। এটি কম্পোজে কম্পোজিশন এবং রিকম্পোজিশন কিভাবে কাজ করে তার কারণে।

প্রাথমিক রচনা এবং পুনর্গঠন সম্পর্কে আরও জানতে, রচনায় চিন্তাভাবনা দেখুন।

কম্পোজেবল রাজ্য

কম্পোজেবল ফাংশন মেমরিতে একটি বস্তু সংরক্ষণ করতে remember API ব্যবহার করতে পারে। remember দ্বারা গণনা করা একটি মান প্রাথমিক রচনার সময় কম্পোজিশনে সংরক্ষণ করা হয় এবং সংরক্ষিত মানটি পুনর্গঠনের সময় ফেরত দেওয়া হয়। remember পরিবর্তনযোগ্য এবং অপরিবর্তনীয় উভয় বস্তু সংরক্ষণ করতে ব্যবহার করা যেতে পারে।

mutableStateOf একটি পর্যবেক্ষণযোগ্য MutableState<T> তৈরি করে, যা কম্পোজ রানটাইমের সাথে একত্রিত একটি পর্যবেক্ষণযোগ্য প্রকার।

interface MutableState<T> : State<T> {
    override var value: T
}

value পড়া যে কোনো কম্পোজযোগ্য ফাংশন এর value সময়সূচী পুনর্গঠন কোনো পরিবর্তন.

একটি কম্পোজেবলে একটি MutableState অবজেক্ট ঘোষণা করার তিনটি উপায় রয়েছে:

  • val mutableState = remember { mutableStateOf(default) }
  • var value by remember { mutableStateOf(default) }
  • val (value, setValue) = remember { mutableStateOf(default) }

এই ঘোষণাগুলি সমতুল্য, এবং রাষ্ট্রের বিভিন্ন ব্যবহারের জন্য সিনট্যাক্স চিনি হিসাবে সরবরাহ করা হয়। আপনি যে কম্পোজেবল লিখছেন তাতে সবচেয়ে সহজে পড়ার কোড তৈরি করে এমন একটি বেছে নেওয়া উচিত।

by ডেলিগেট সিনট্যাক্সের জন্য নিম্নলিখিত আমদানি প্রয়োজন:

import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue

কোন কম্পোজেবলগুলি প্রদর্শিত হবে তা পরিবর্তন করতে আপনি অন্যান্য কম্পোজেবলের প্যারামিটার বা এমনকি বিবৃতিতে যুক্তি হিসাবে মনে রাখা মান ব্যবহার করতে পারেন। উদাহরণস্বরূপ, নামটি খালি থাকলে আপনি যদি অভিবাদনটি প্রদর্শন করতে না চান তবে একটি if বিবৃতিতে রাষ্ট্রটি ব্যবহার করুন:

@Composable
fun HelloContent() {
    Column(modifier = Modifier.padding(16.dp)) {
        var name by remember { mutableStateOf("") }
        if (name.isNotEmpty()) {
            Text(
                text = "Hello, $name!",
                modifier = Modifier.padding(bottom = 8.dp),
                style = MaterialTheme.typography.bodyMedium
            )
        }
        OutlinedTextField(
            value = name,
            onValueChange = { name = it },
            label = { Text("Name") }
        )
    }
}

যদিও remember আপনাকে পুনর্গঠন জুড়ে স্থিতি বজায় রাখতে সহায়তা করে, তবে কনফিগারেশন পরিবর্তনগুলির মধ্যে রাজ্যটি বজায় রাখা হয় না। এর জন্য, আপনাকে rememberSaveable ব্যবহার করতে হবে। rememberSaveable স্বয়ংক্রিয়ভাবে যে কোনও মান সংরক্ষণ করে যা একটি Bundle সংরক্ষণ করা যেতে পারে। অন্যান্য মানগুলির জন্য, আপনি একটি কাস্টম সেভার অবজেক্টে পাস করতে পারেন।

রাষ্ট্রের অন্যান্য সমর্থিত প্রকার

রচনার প্রয়োজন নেই যে আপনি স্থিতি ধরে রাখতে MutableState<T> ব্যবহার করবেন; এটি অন্যান্য পর্যবেক্ষণযোগ্য ধরনের সমর্থন করে। কম্পোজে আরেকটি পর্যবেক্ষণযোগ্য টাইপ পড়ার আগে, আপনাকে অবশ্যই এটিকে একটি State<T> এ রূপান্তর করতে হবে যাতে কম্পোজেবলগুলি স্বয়ংক্রিয়ভাবে কম্পোজ করতে পারে যখন স্টেট পরিবর্তন হয়।

Android অ্যাপ্লিকেশানগুলিতে ব্যবহৃত সাধারণ পর্যবেক্ষণযোগ্য প্রকারগুলি থেকে State<T> তৈরি করতে ফাংশন সহ জাহাজগুলি রচনা করুন৷ এই ইন্টিগ্রেশনগুলি ব্যবহার করার আগে, নীচের রূপরেখা অনুযায়ী উপযুক্ত নিদর্শন (গুলি) যোগ করুন:

  • Flow : collectAsStateWithLifecycle()

    collectAsStateWithLifecycle() একটি লাইফসাইকেল-সচেতন পদ্ধতিতে একটি Flow থেকে মান সংগ্রহ করে, যা আপনার অ্যাপকে অ্যাপ সংস্থান সংরক্ষণ করতে দেয়। এটি কম্পোজ State থেকে সর্বশেষ নির্গত মান উপস্থাপন করে। Android অ্যাপ্লিকেশানগুলিতে ফ্লো সংগ্রহ করার প্রস্তাবিত উপায় হিসাবে এই APIটি ব্যবহার করুন৷

    build.gradle ফাইলে নিম্নলিখিত নির্ভরতা প্রয়োজন (এটি 2.6.0-beta01 বা নতুন হওয়া উচিত):

কোটলিন

dependencies {
      ...
      implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.2")
}

গ্রোভি

dependencies {
      ...
      implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.2"
}
  • Flow : collectAsState()

    collectAsState হল collectAsStateWithLifecycle এর অনুরূপ, কারণ এটি একটি Flow থেকে মান সংগ্রহ করে এবং কম্পোজ State রূপান্তরিত করে।

    প্ল্যাটফর্ম-অজ্ঞেয়বাদী কোডের জন্য collectAsStateWithLifecycle এর পরিবর্তে collectAsState ব্যবহার করুন, যা শুধুমাত্র Android-এর জন্য।

    collectAsState এর জন্য অতিরিক্ত নির্ভরতার প্রয়োজন নেই, কারণ এটি compose-runtime উপলব্ধ।

  • LiveData : observeAsState()

    observeAsState() এই LiveData পর্যবেক্ষণ করা শুরু করে এবং State মাধ্যমে এর মানগুলিকে উপস্থাপন করে।

    build.gradle ফাইলে নিম্নলিখিত নির্ভরতা প্রয়োজন:

কোটলিন

dependencies {
      ...
      implementation("androidx.compose.runtime:runtime-livedata:1.6.8")
}

গ্রোভি

dependencies {
      ...
      implementation "androidx.compose.runtime:runtime-livedata:1.6.8"
}
  • RxJava2 : subscribeAsState()

    subscribeAsState() হল এক্সটেনশন ফাংশন যা RxJava2 এর প্রতিক্রিয়াশীল স্ট্রীমগুলিকে (যেমন Single , Observable , Completable ) কম্পোজ State রূপান্তরিত করে।

    build.gradle ফাইলে নিম্নলিখিত নির্ভরতা প্রয়োজন:

কোটলিন

dependencies {
      ...
      implementation("androidx.compose.runtime:runtime-rxjava2:1.6.8")
}

গ্রোভি

dependencies {
      ...
      implementation "androidx.compose.runtime:runtime-rxjava2:1.6.8"
}
  • RxJava3 : subscribeAsState()

    subscribeAsState() হল এক্সটেনশন ফাংশন যা RxJava3 এর প্রতিক্রিয়াশীল স্ট্রীমগুলিকে (যেমন Single , Observable , Completable ) কম্পোজ State রূপান্তরিত করে।

    build.gradle ফাইলে নিম্নলিখিত নির্ভরতা প্রয়োজন:

কোটলিন

dependencies {
      ...
      implementation("androidx.compose.runtime:runtime-rxjava3:1.6.8")
}

গ্রোভি

dependencies {
      ...
      implementation "androidx.compose.runtime:runtime-rxjava3:1.6.8"
}

রাষ্ট্রীয় বনাম রাষ্ট্রহীন

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

একটি স্টেটলেস কম্পোজেবল হল একটি কম্পোজেবল যা কোনো স্টেট ধরে না। রাষ্ট্রহীনতা অর্জনের একটি সহজ উপায় হল রাষ্ট্র উত্তোলন ব্যবহার করা।

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

রাজ্য উত্তোলন

কম্পোজে স্টেট হোস্টিং হল একটি কম্পোজেবল স্টেটলেস করার জন্য কম্পোজেবলের কলারে স্টেট সরানোর একটি প্যাটার্ন। জেটপ্যাক কম্পোজে স্টেট হোস্টিং এর সাধারণ প্যাটার্ন হল স্টেট ভেরিয়েবলকে দুটি প্যারামিটার দিয়ে প্রতিস্থাপন করা:

  • value: T : প্রদর্শনের জন্য বর্তমান মান
  • onValueChange: (T) -> Unit : একটি ইভেন্ট যা মান পরিবর্তনের অনুরোধ করে, যেখানে T হল প্রস্তাবিত নতুন মান

যাইহোক, আপনি onValueChange এ সীমাবদ্ধ নন। যদি আরও নির্দিষ্ট ঘটনাগুলি কম্পোজেবলের জন্য উপযুক্ত হয়, তাহলে আপনাকে ল্যাম্বডাস ব্যবহার করে সেগুলি সংজ্ঞায়িত করা উচিত।

এইভাবে উত্তোলিত রাজ্যের কিছু গুরুত্বপূর্ণ বৈশিষ্ট্য রয়েছে:

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

উদাহরণের ক্ষেত্রে, আপনি HelloContent থেকে name এবং onValueChange বের করুন এবং সেগুলিকে একটি HelloScreen কম্পোজেবলে নিয়ে যান যেটিকে HelloContent বলে।

@Composable
fun HelloScreen() {
    var name by rememberSaveable { mutableStateOf("") }

    HelloContent(name = name, onNameChange = { name = it })
}

@Composable
fun HelloContent(name: String, onNameChange: (String) -> Unit) {
    Column(modifier = Modifier.padding(16.dp)) {
        Text(
            text = "Hello, $name",
            modifier = Modifier.padding(bottom = 8.dp),
            style = MaterialTheme.typography.bodyMedium
        )
        OutlinedTextField(value = name, onValueChange = onNameChange, label = { Text("Name") })
    }
}

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

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

আরও জানতে রাজ্যের পৃষ্ঠাটি কোথায় উত্তোলন করবেন তা দেখুন।

রচনায় স্থিতি পুনরুদ্ধার করা হচ্ছে

মনে rememberSaveable এপিআই remember মতো আচরণ করে কারণ এটি সংরক্ষিত ইনস্ট্যান্স স্টেট মেকানিজম ব্যবহার করে পুনর্গঠন জুড়ে এবং কার্যকলাপ বা প্রক্রিয়া বিনোদন জুড়ে অবস্থা বজায় রাখে। উদাহরণস্বরূপ, এটি ঘটে, যখন স্ক্রিনটি ঘোরানো হয়।

রাষ্ট্র সংরক্ষণের উপায়

Bundle যোগ করা সমস্ত ডেটা প্রকার স্বয়ংক্রিয়ভাবে সংরক্ষিত হয়। আপনি যদি এমন কিছু সংরক্ষণ করতে চান যা Bundle যোগ করা যায় না, সেখানে বেশ কয়েকটি বিকল্প রয়েছে।

পার্সেলাইজ করুন

সহজ সমাধান হল অবজেক্টে @Parcelize টীকা যোগ করা। বস্তুটি parcelable হয়ে যায়, এবং বান্ডিল করা যায়। উদাহরণস্বরূপ, এই কোডটি একটি পার্সেলযোগ্য City ডেটা টাইপ তৈরি করে এবং এটি রাজ্যে সংরক্ষণ করে।

@Parcelize
data class City(val name: String, val country: String) : Parcelable

@Composable
fun CityScreen() {
    var selectedCity = rememberSaveable {
        mutableStateOf(City("Madrid", "Spain"))
    }
}

ম্যাপসেভার

যদি কোনো কারণে @Parcelize উপযুক্ত না হয়, তাহলে আপনি একটি বস্তুকে মানগুলির একটি সেটে রূপান্তর করার জন্য আপনার নিজস্ব নিয়ম সংজ্ঞায়িত করতে mapSaver ব্যবহার করতে পারেন যা সিস্টেম Bundle সংরক্ষণ করতে পারে।

data class City(val name: String, val country: String)

val CitySaver = run {
    val nameKey = "Name"
    val countryKey = "Country"
    mapSaver(
        save = { mapOf(nameKey to it.name, countryKey to it.country) },
        restore = { City(it[nameKey] as String, it[countryKey] as String) }
    )
}

@Composable
fun CityScreen() {
    var selectedCity = rememberSaveable(stateSaver = CitySaver) {
        mutableStateOf(City("Madrid", "Spain"))
    }
}

লিস্টসেভার

মানচিত্রের জন্য কীগুলি সংজ্ঞায়িত করার প্রয়োজন এড়াতে, আপনি listSaver ব্যবহার করতে পারেন এবং কী হিসাবে এর সূচকগুলি ব্যবহার করতে পারেন:

data class City(val name: String, val country: String)

val CitySaver = listSaver<City, Any>(
    save = { listOf(it.name, it.country) },
    restore = { City(it[0] as String, it[1] as String) }
)

@Composable
fun CityScreen() {
    var selectedCity = rememberSaveable(stateSaver = CitySaver) {
        mutableStateOf(City("Madrid", "Spain"))
    }
}

কম্পোজ রাষ্ট্র ধারক

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

আরও জানতে আর্কিটেকচার গাইডে কম্পোজ ডকুমেন্টেশনে স্টেট হোস্টিং দেখুন বা, আরও সাধারণভাবে, স্টেট হোল্ডার এবং ইউআই স্টেট পৃষ্ঠা দেখুন।

কী পরিবর্তন হলে রিট্রিগার গণনা মনে রাখবেন

remember API প্রায়শই MutableState এর সাথে একসাথে ব্যবহার করা হয়:

var name by remember { mutableStateOf("") }

এখানে, remember ফাংশন ব্যবহার করে MutableState মানকে পুনর্গঠন করে।

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

ক্যাশিং স্টেট ছাড়াও, আপনি কম্পোজিশনে যেকোন বস্তু বা অপারেশনের ফলাফল সংরক্ষণ করতে remember ব্যবহার করতে পারেন যা শুরু বা গণনা করা ব্যয়বহুল। আপনি হয়ত প্রতিটি পুনর্গঠনে এই গণনার পুনরাবৃত্তি করতে চান না। একটি উদাহরণ এই ShaderBrush অবজেক্ট তৈরি করছে, যা একটি ব্যয়বহুল অপারেশন:

val brush = remember {
    ShaderBrush(
        BitmapShader(
            ImageBitmap.imageResource(res, avatarRes).asAndroidBitmap(),
            Shader.TileMode.REPEAT,
            Shader.TileMode.REPEAT
        )
    )
}

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

নিম্নলিখিত উদাহরণগুলি দেখায় যে এই প্রক্রিয়াটি কীভাবে কাজ করে।

এই স্নিপেটে, একটি ShaderBrush তৈরি করা হয় এবং একটি Box কম্পোজেবলের ব্যাকগ্রাউন্ড পেইন্ট হিসাবে ব্যবহার করা হয়। remember ShaderBrush দৃষ্টান্ত সংরক্ষণ করুন কারণ এটি পুনরায় তৈরি করা ব্যয়বহুল, যেমনটি আগে ব্যাখ্যা করা হয়েছে। remember avatarRes key1 প্যারামিটার হিসেবে নেয়, যা নির্বাচিত ব্যাকগ্রাউন্ড ইমেজ। যদি avatarRes পরিবর্তিত হয়, ব্রাশটি নতুন চিত্রের সাথে পুনরায় সংমিশ্রিত হয় এবং Box পুনরায় প্রয়োগ করা হয়। এটি ঘটতে পারে যখন ব্যবহারকারী একটি পিকার থেকে পটভূমি হতে অন্য একটি ছবি নির্বাচন করেন।

@Composable
private fun BackgroundBanner(
    @DrawableRes avatarRes: Int,
    modifier: Modifier = Modifier,
    res: Resources = LocalContext.current.resources
) {
    val brush = remember(key1 = avatarRes) {
        ShaderBrush(
            BitmapShader(
                ImageBitmap.imageResource(res, avatarRes).asAndroidBitmap(),
                Shader.TileMode.REPEAT,
                Shader.TileMode.REPEAT
            )
        )
    }

    Box(
        modifier = modifier.background(brush)
    ) {
        /* ... */
    }
}

পরবর্তী স্নিপেটে, স্টেটকে একটি প্লেইন স্টেট হোল্ডার ক্লাস MyAppState এ উত্তোলন করা হয়। এটি remember ব্যবহার করে ক্লাসের একটি ইন্সট্যান্স আরম্ভ করার জন্য একটি rememberMyAppState ফাংশন প্রকাশ করে। কম্পোজে টিকে থাকা একটি দৃষ্টান্ত তৈরি করতে এই ধরনের ফাংশনগুলিকে প্রকাশ করা কম্পোজের একটি সাধারণ প্যাটার্ন। rememberMyAppState ফাংশন windowSizeClass পায়, যা remember key প্যারামিটার হিসেবে কাজ করে। যদি এই প্যারামিটারটি পরিবর্তিত হয়, অ্যাপটিকে সাম্প্রতিক মান সহ প্লেইন স্টেট হোল্ডার ক্লাস পুনরায় তৈরি করতে হবে। এটি ঘটতে পারে যদি, উদাহরণস্বরূপ, ব্যবহারকারী ডিভাইসটি ঘোরান।

@Composable
private fun rememberMyAppState(
    windowSizeClass: WindowSizeClass
): MyAppState {
    return remember(windowSizeClass) {
        MyAppState(windowSizeClass)
    }
}

@Stable
class MyAppState(
    private val windowSizeClass: WindowSizeClass
) { /* ... */ }

একটি কী পরিবর্তিত হয়েছে কিনা তা নির্ধারণ করতে এবং সঞ্চিত মানটিকে অবৈধ করে কিনা তা নির্ধারণ করতে কম্পোজ ক্লাসের সমান বাস্তবায়ন ব্যবহার করে।

পুনঃগঠনের বাইরে কী সহ স্টেট স্টোর করুন

rememberSaveable এপিআই হল remember চারপাশে একটি মোড়ক যা একটি Bundle ডেটা সংরক্ষণ করতে পারে। এই এপিআই রাষ্ট্রকে শুধুমাত্র পুনর্গঠনই নয়, ক্রিয়াকলাপ বিনোদন এবং সিস্টেম-প্রবর্তিত প্রক্রিয়ার মৃত্যুতেও বেঁচে থাকতে দেয়। rememberSaveable একই উদ্দেশ্যে input পরামিতি গ্রহণ করে যা remember keys গ্রহণ করে। কোনো ইনপুট পরিবর্তন হলে ক্যাশে অবৈধ হয়ে যায় । পরের বার যখন ফাংশনটি পুনরায় কম্পোজ করা হয়, rememberSaveable গণনা ল্যাম্বডা ব্লকটিকে পুনরায় কার্যকর করে।

নিম্নলিখিত উদাহরণে, typedQuery পরিবর্তন না হওয়া পর্যন্ত rememberSaveable userTypedQuery সংরক্ষণ করে:

var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) {
    mutableStateOf(
        TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length))
    )
}

আরও জানুন

রাজ্য এবং জেটপ্যাক রচনা সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন৷

নমুনা

কোডল্যাব

ভিডিও

ব্লগ

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