জেটপ্যাক কম্পোজ অ্যান্ড্রয়েডের জন্য একটি আধুনিক ঘোষণামূলক UI টুলকিট। কম্পোজ একটি ঘোষণামূলক API প্রদান করে আপনার অ্যাপ UI লিখতে এবং বজায় রাখা সহজ করে তোলে যা আপনাকে ফ্রন্টএন্ড ভিউ মিউটেশন না করে আপনার অ্যাপ UI রেন্ডার করতে দেয়। এই পরিভাষাটির কিছু ব্যাখ্যা প্রয়োজন, কিন্তু প্রভাবগুলি আপনার অ্যাপ ডিজাইনের জন্য গুরুত্বপূর্ণ।
ঘোষণামূলক প্রোগ্রামিং দৃষ্টান্ত
ঐতিহাসিকভাবে, একটি অ্যান্ড্রয়েড ভিউ হায়ারার্কি UI উইজেটগুলির একটি ট্রি হিসাবে উপস্থাপনযোগ্য। ব্যবহারকারীর ইন্টারঅ্যাকশনের মতো জিনিসগুলির কারণে অ্যাপের অবস্থা পরিবর্তন হওয়ার কারণে, বর্তমান ডেটা প্রদর্শনের জন্য UI শ্রেণিবিন্যাস আপডেট করা প্রয়োজন। UI আপডেট করার সবচেয়ে সাধারণ উপায় হল findViewById()
মত ফাংশন ব্যবহার করে গাছে হাঁটা এবং button.setText(String)
, container.addChild(View)
বা img.setImageBitmap(Bitmap)
মত পদ্ধতিতে কল করে নোড পরিবর্তন করা। এই পদ্ধতিগুলি উইজেটের অভ্যন্তরীণ অবস্থা পরিবর্তন করে।
ম্যানুয়ালি ভিউ ম্যানিপুলেট করা ত্রুটির সম্ভাবনা বাড়ায়। যদি ডেটার একটি অংশ একাধিক জায়গায় রেন্ডার করা হয়, তবে এটি দেখায় এমন ভিউগুলির একটি আপডেট করতে ভুলে যাওয়া সহজ। অবৈধ রাষ্ট্র তৈরি করাও সহজ, যখন দুটি আপডেট একটি অপ্রত্যাশিত উপায়ে বিরোধিতা করে। উদাহরণস্বরূপ, একটি আপডেট একটি নোডের মান সেট করার চেষ্টা করতে পারে যা এইমাত্র UI থেকে সরানো হয়েছে। সাধারণভাবে, সফ্টওয়্যার রক্ষণাবেক্ষণের জটিলতা আপডেট করার প্রয়োজনের ভিউ সংখ্যার সাথে বৃদ্ধি পায়।
গত বেশ কয়েক বছর ধরে, পুরো শিল্পটি একটি ঘোষণামূলক UI মডেলে স্থানান্তরিত হতে শুরু করেছে, যা ব্যবহারকারীর ইন্টারফেস তৈরি এবং আপডেট করার সাথে যুক্ত ইঞ্জিনিয়ারিংকে ব্যাপকভাবে সরল করে। কৌশলটি ধারণাগতভাবে পুরো স্ক্রিনটিকে স্ক্র্যাচ থেকে পুনরুত্পাদন করে, তারপর শুধুমাত্র প্রয়োজনীয় পরিবর্তনগুলি প্রয়োগ করে কাজ করে। এই পদ্ধতিটি ম্যানুয়ালি একটি স্টেটফুল ভিউ হায়ারার্কি আপডেট করার জটিলতা এড়ায়। রচনা একটি ঘোষণামূলক UI ফ্রেমওয়ার্ক।
পুরো স্ক্রিন পুনরুত্থিত করার সাথে একটি চ্যালেঞ্জ হল এটি সম্ভাব্য ব্যয়বহুল, সময়, কম্পিউটিং শক্তি এবং ব্যাটারি ব্যবহারের ক্ষেত্রে। এই খরচ কমাতে, কম্পোজ বুদ্ধিমত্তার সাথে চয়ন করে যে UI-এর কোন অংশগুলি যেকোন সময়ে পুনরায় আঁকতে হবে। আপনি কীভাবে আপনার UI উপাদানগুলি ডিজাইন করেন তার জন্য এর কিছু প্রভাব রয়েছে, যেমন Recomposition এ আলোচনা করা হয়েছে।
একটি সহজ কম্পোজযোগ্য ফাংশন
রচনা ব্যবহার করে, আপনি কম্পোজযোগ্য ফাংশনগুলির একটি সেট সংজ্ঞায়িত করে আপনার ব্যবহারকারী ইন্টারফেস তৈরি করতে পারেন যা ডেটা গ্রহণ করে এবং UI উপাদানগুলি নির্গত করে। একটি সাধারণ উদাহরণ হল একটি Greeting
উইজেট, যা একটি String
নেয় এবং একটি Text
উইজেট নির্গত করে যা একটি শুভেচ্ছা বার্তা প্রদর্শন করে।
চিত্র 1. একটি সাধারণ সংমিশ্রণযোগ্য ফাংশন যা ডেটা পাস করে এবং এটি পর্দায় একটি পাঠ্য উইজেট রেন্ডার করতে ব্যবহার করে।
এই ফাংশন সম্পর্কে কয়েকটি উল্লেখযোগ্য বিষয়:
ফাংশনটি
@Composable
টীকা দিয়ে টীকা করা হয়েছে। সমস্ত কম্পোজযোগ্য ফাংশনে এই টীকা থাকতে হবে; এই টীকাটি কম্পোজ কম্পাইলারকে জানায় যে এই ফাংশনটি ডেটাকে UI-তে রূপান্তর করার উদ্দেশ্যে।ফাংশন ডেটা নেয়। কম্পোজেবল ফাংশন পরামিতি গ্রহণ করতে পারে, যা অ্যাপ লজিককে UI বর্ণনা করতে দেয়। এই ক্ষেত্রে, আমাদের উইজেট একটি
String
গ্রহণ করে যাতে এটি নাম দ্বারা ব্যবহারকারীকে অভিবাদন জানাতে পারে।ফাংশনটি UI-তে পাঠ্য প্রদর্শন করে। এটি
Text()
কম্পোজেবল ফাংশনকে কল করে তা করে, যা আসলে টেক্সট UI উপাদান তৈরি করে। কম্পোজযোগ্য ফাংশনগুলি অন্যান্য কম্পোজেবল ফাংশনগুলিকে কল করে UI অনুক্রম নির্গত করে।ফাংশন কিছু ফেরত না. যে ফাংশনগুলি UI নির্গত করে তাদের কিছু ফেরত দেওয়ার দরকার নেই, কারণ তারা UI উইজেটগুলি তৈরি করার পরিবর্তে পছন্দসই স্ক্রীনের অবস্থা বর্ণনা করে।
এই ফাংশনটি দ্রুত, অদম্য এবং পার্শ্বপ্রতিক্রিয়ামুক্ত ।
- একই আর্গুমেন্টের সাথে একাধিকবার কল করা হলে ফাংশনটি একইভাবে আচরণ করে এবং এটি গ্লোবাল ভেরিয়েবল বা
random()
তে কল করার মতো অন্যান্য মান ব্যবহার করে না। - ফাংশনটি কোনো পার্শ্ব-প্রতিক্রিয়া ছাড়াই UI বর্ণনা করে, যেমন বৈশিষ্ট্য পরিবর্তন করা বা গ্লোবাল ভেরিয়েবল।
সাধারণভাবে, সমস্ত সংমিশ্রণযোগ্য ফাংশনগুলিকে এই বৈশিষ্ট্যগুলির সাথে লিখতে হবে, কারণগুলি পুনর্গঠনে আলোচনা করা হয়েছে।
- একই আর্গুমেন্টের সাথে একাধিকবার কল করা হলে ফাংশনটি একইভাবে আচরণ করে এবং এটি গ্লোবাল ভেরিয়েবল বা
ঘোষণামূলক প্যারাডাইম শিফট
অনেক প্রয়োজনীয় অবজেক্ট-ওরিয়েন্টেড UI টুলকিট সহ, আপনি উইজেটের একটি ট্রি ইনস্ট্যান্টিয়েট করে UI আরম্ভ করেন। আপনি প্রায়শই একটি XML লেআউট ফাইল স্ফীত করে এটি করেন। প্রতিটি উইজেট তার নিজস্ব অভ্যন্তরীণ অবস্থা বজায় রাখে এবং গেটার এবং সেটার পদ্ধতিগুলিকে প্রকাশ করে যা অ্যাপ লজিককে উইজেটের সাথে ইন্টারঅ্যাক্ট করার অনুমতি দেয়।
রচনার ঘোষণামূলক পদ্ধতিতে, উইজেটগুলি তুলনামূলকভাবে রাষ্ট্রহীন এবং সেটার বা গেটার ফাংশন প্রকাশ করে না। আসলে, উইজেটগুলি বস্তু হিসাবে উন্মুক্ত হয় না। আপনি বিভিন্ন আর্গুমেন্ট সহ একই কম্পোজেবল ফাংশন কল করে UI আপডেট করেন। এটি একটি ViewModel
মতো আর্কিটেকচারাল প্যাটার্নে স্টেট প্রদান করা সহজ করে তোলে, যেমনটি অ্যাপ আর্কিটেকচারের গাইডে বর্ণিত হয়েছে। তারপর, আপনার কম্পোজেবলগুলি প্রতিবার পর্যবেক্ষণযোগ্য ডেটা আপডেট হওয়ার সময় বর্তমান অ্যাপ্লিকেশন অবস্থাকে একটি UI-তে রূপান্তর করার জন্য দায়ী।
চিত্র 2. অ্যাপ লজিক টপ-লেভেল কম্পোজেবল ফাংশনে ডেটা প্রদান করে। এই ফাংশনটি অন্যান্য কম্পোজেবলকে কল করে UI বর্ণনা করতে ডেটা ব্যবহার করে এবং সেই কম্পোজেবলগুলিতে এবং অনুক্রমের নিচে যথাযথ ডেটা পাঠায়।
ব্যবহারকারী যখন UI এর সাথে ইন্টারঅ্যাক্ট করে, তখন UI ইভেন্ট উত্থাপন করে যেমন onClick
। সেই ইভেন্টগুলি অ্যাপের যুক্তিকে অবহিত করা উচিত, যা তারপরে অ্যাপের অবস্থা পরিবর্তন করতে পারে। যখন অবস্থা পরিবর্তিত হয়, তখন কম্পোজযোগ্য ফাংশনগুলিকে নতুন ডেটা সহ আবার কল করা হয়। এটি UI উপাদানগুলিকে পুনরায় আঁকার কারণ করে--এই প্রক্রিয়াটিকে পুনর্গঠন বলা হয়।
চিত্র 3. ব্যবহারকারী একটি UI উপাদানের সাথে ইন্টারঅ্যাক্ট করেছে, যার ফলে একটি ইভেন্ট ট্রিগার হয়েছে৷ অ্যাপ লজিক ইভেন্টে সাড়া দেয়, তারপর প্রয়োজন হলে কম্পোজেবল ফাংশনগুলি স্বয়ংক্রিয়ভাবে নতুন প্যারামিটার সহ আবার কল করা হয়।
গতিশীল বিষয়বস্তু
যেহেতু কম্পোজেবল ফাংশনগুলি XML-এর পরিবর্তে Kotlin-এ লেখা হয়, সেগুলি অন্য কোটলিন কোডের মতোই গতিশীল হতে পারে। উদাহরণস্বরূপ, ধরুন আপনি একটি UI তৈরি করতে চান যা ব্যবহারকারীদের একটি তালিকাকে শুভেচ্ছা জানায়:
@Composable fun Greeting(names: List<String>) { for (name in names) { Text("Hello $name") } }
এই ফাংশনটি নামের একটি তালিকা নেয় এবং প্রতিটি ব্যবহারকারীর জন্য একটি অভিবাদন তৈরি করে। কম্পোজযোগ্য ফাংশন বেশ পরিশীলিত হতে পারে। আপনি একটি নির্দিষ্ট UI উপাদান দেখাতে চান কিনা তা নির্ধারণ করতে আপনি if
বিবৃতি ব্যবহার করতে পারেন। আপনি loops ব্যবহার করতে পারেন. আপনি সহায়ক ফাংশন কল করতে পারেন. আপনার অন্তর্নিহিত ভাষার সম্পূর্ণ নমনীয়তা আছে। এই শক্তি এবং নমনীয়তা জেটপ্যাক রচনার অন্যতম প্রধান সুবিধা।
পুনর্গঠন
একটি বাধ্যতামূলক UI মডেলে, একটি উইজেট পরিবর্তন করতে, আপনি উইজেটের অভ্যন্তরীণ অবস্থা পরিবর্তন করতে একটি সেটারকে কল করেন। কম্পোজে, আপনি নতুন ডেটা সহ কম্পোজযোগ্য ফাংশনটিকে আবার কল করুন। এটি করার ফলে ফাংশনটি পুনরায় কম্পোজ করা হয় -- ফাংশন দ্বারা নির্গত উইজেটগুলি নতুন ডেটা সহ প্রয়োজনে পুনরায় আঁকা হয়। কম্পোজ ফ্রেমওয়ার্ক বুদ্ধিমত্তার সাথে শুধুমাত্র পরিবর্তিত উপাদানগুলিকে পুনরায় কম্পোজ করতে পারে।
উদাহরণস্বরূপ, এই সংমিশ্রণযোগ্য ফাংশনটি বিবেচনা করুন যা একটি বোতাম প্রদর্শন করে:
@Composable fun ClickCounter(clicks: Int, onClick: () -> Unit) { Button(onClick = onClick) { Text("I've been clicked $clicks times") } }
প্রতিবার বোতামটি ক্লিক করা হলে, কলার clicks
মান আপডেট করে। কম্পোজ নতুন মান দেখানোর জন্য আবার Text
ফাংশন সহ ল্যাম্বডাকে কল করে; এই প্রক্রিয়াটিকে বলা হয় পুনর্গঠন । অন্যান্য ফাংশন যা মানের উপর নির্ভর করে না সেগুলি পুনর্গঠিত হয় না।
যেমনটি আমরা আলোচনা করেছি, সমগ্র UI ট্রি পুনরায় কম্পোজ করা গণনাগতভাবে ব্যয়বহুল হতে পারে, যা কম্পিউটিং শক্তি এবং ব্যাটারি লাইফ ব্যবহার করে। রচনা এই বুদ্ধিমান পুনর্গঠনের সাথে এই সমস্যার সমাধান করে।
পুনর্গঠন হল ইনপুট পরিবর্তন হলে আপনার কম্পোজযোগ্য ফাংশনগুলিকে আবার কল করার প্রক্রিয়া। এটি ঘটে যখন ফাংশনের ইনপুট পরিবর্তন হয়। যখন কম্পোজ নতুন ইনপুটগুলির উপর ভিত্তি করে পুনর্গঠন করা হয়, তখন এটি শুধুমাত্র সেই ফাংশন বা ল্যাম্বডাসগুলিকে কল করে যা পরিবর্তিত হতে পারে এবং বাকিগুলি এড়িয়ে যায়। পরিবর্তিত প্যারামিটার নেই এমন সমস্ত ফাংশন বা ল্যাম্বডাস বাদ দিয়ে, রচনা দক্ষতার সাথে পুনরায় রচনা করতে পারে।
সংমিশ্রণযোগ্য ফাংশনগুলি কার্যকর করার পার্শ্ব-প্রতিক্রিয়াগুলির উপর নির্ভর করবেন না, যেহেতু একটি ফাংশনের পুনর্গঠন এড়িয়ে যেতে পারে। যদি আপনি তা করেন, ব্যবহারকারীরা আপনার অ্যাপে অদ্ভুত এবং অপ্রত্যাশিত আচরণ অনুভব করতে পারে। একটি পার্শ্ব-প্রতিক্রিয়া হল যেকোনো পরিবর্তন যা আপনার বাকি অ্যাপে দৃশ্যমান। উদাহরণস্বরূপ, এই ক্রিয়াগুলি সমস্ত বিপজ্জনক পার্শ্ব প্রতিক্রিয়া:
- একটি ভাগ করা বস্তুর একটি সম্পত্তি লেখা
-
ViewModel
এ একটি পর্যবেক্ষণযোগ্য আপডেট করা হচ্ছে - ভাগ করা পছন্দ আপডেট করা হচ্ছে
কম্পোজেবল ফাংশনগুলি প্রতি ফ্রেমের মতো প্রায়ই পুনঃনির্বাহিত হতে পারে, যেমন যখন একটি অ্যানিমেশন রেন্ডার করা হচ্ছে। অ্যানিমেশনের সময় জ্যাঙ্ক এড়াতে কম্পোজযোগ্য ফাংশনগুলি দ্রুত হওয়া উচিত। আপনার যদি ব্যয়বহুল ক্রিয়াকলাপগুলি করতে হয়, যেমন ভাগ করা পছন্দগুলি থেকে পড়া, এটি একটি ব্যাকগ্রাউন্ড কোরোটিনে করুন এবং মান ফলাফলটিকে একটি প্যারামিটার হিসাবে কম্পোজেবল ফাংশনে পাস করুন৷
একটি উদাহরণ হিসাবে, এই কোডটি SharedPreferences
এ একটি মান আপডেট করার জন্য একটি রচনাযোগ্য তৈরি করে। কম্পোজেবল শেয়ার করা পছন্দ থেকে পড়া বা লেখা উচিত নয়। পরিবর্তে, এই কোডটি পঠন এবং লেখাকে একটি পটভূমি কোরোটিনে একটি ViewModel
নিয়ে যায়। অ্যাপ লজিক একটি আপডেট ট্রিগার করতে একটি কলব্যাক সহ বর্তমান মান পাস করে।
@Composable fun SharedPrefsToggle( text: String, value: Boolean, onValueChanged: (Boolean) -> Unit ) { Row { Text(text) Checkbox(checked = value, onCheckedChange = onValueChanged) } }
আপনি যখন রচনা ব্যবহার করেন তখন এই দস্তাবেজটি বেশ কয়েকটি বিষয় নিয়ে আলোচনা করে:
- পুনর্গঠন যতটা সম্ভব কম্পোজেবল ফাংশন এবং ল্যাম্বডাস এড়িয়ে যায়।
- পুনর্গঠন আশাবাদী এবং বাতিল হতে পারে।
- একটি সংমিশ্রণযোগ্য ফাংশন বেশ ঘন ঘন চালানো হতে পারে, যেমন প্রায়শই একটি অ্যানিমেশনের প্রতিটি ফ্রেম।
- কম্পোজযোগ্য ফাংশন সমান্তরালভাবে কার্যকর করতে পারে।
- কম্পোজেবল ফাংশন যেকোন ক্রমে এক্সিকিউট করতে পারে।
নিম্নলিখিত বিভাগগুলি পুনর্গঠন সমর্থন করার জন্য কম্পোজযোগ্য ফাংশনগুলি কীভাবে তৈরি করা যায় তা কভার করবে। প্রতিটি ক্ষেত্রে, সর্বোত্তম অনুশীলন হল আপনার কম্পোজেবল ফাংশনগুলিকে দ্রুত, অদম্য এবং পার্শ্ব-প্রতিক্রিয়া মুক্ত রাখা।
পুনর্গঠন যতটা সম্ভব এড়িয়ে যায়
যখন আপনার UI-এর অংশগুলি অবৈধ হয়, তখন কম্পোজ সেই অংশগুলিকে পুনরায় কম্পোজ করার জন্য সর্বোত্তম চেষ্টা করে যা আপডেট করা দরকার৷ এর অর্থ হল এটি UI ট্রিতে উপরে বা নীচের কোনো কম্পোজেবল এক্সিকিউট না করে একটি একক বোতামের কম্পোজেবল পুনরায় চালানোর জন্য এড়িয়ে যেতে পারে।
প্রতিটি সংমিশ্রণযোগ্য ফাংশন এবং ল্যাম্বডা নিজেই পুনরায় সংমিশ্রণ করতে পারে। এখানে একটি উদাহরণ রয়েছে যা প্রদর্শন করে যে কীভাবে একটি তালিকা রেন্ডার করার সময় পুনর্গঠন কিছু উপাদান এড়িয়ে যেতে পারে:
/** * Display a list of names the user can click with a header */ @Composable fun NamePicker( header: String, names: List<String>, onNameClicked: (String) -> Unit ) { Column { // this will recompose when [header] changes, but not when [names] changes Text(header, style = MaterialTheme.typography.bodyLarge) HorizontalDivider() // LazyColumn is the Compose version of a RecyclerView. // The lambda passed to items() is similar to a RecyclerView.ViewHolder. LazyColumn { items(names) { name -> // When an item's [name] updates, the adapter for that item // will recompose. This will not recompose when [header] changes NamePickerItem(name, onNameClicked) } } } } /** * Display a single name the user can click. */ @Composable private fun NamePickerItem(name: String, onClicked: (String) -> Unit) { Text(name, Modifier.clickable(onClick = { onClicked(name) })) }
এই স্কোপগুলির প্রতিটি একটি পুনর্গঠনের সময় চালানোর একমাত্র জিনিস হতে পারে। header
পরিবর্তিত হলে কম্পোজ তার পিতামাতার কাউকে কার্যকর না করেই Column
ল্যাম্বডায় চলে যেতে পারে। এবং Column
চালানোর সময়, names
পরিবর্তন না হলে রচনা LazyColumn
এর আইটেমগুলি এড়িয়ে যেতে পারে।
আবার, সমস্ত সংমিশ্রণযোগ্য ফাংশন বা ল্যাম্বডাস সম্পাদন করা পার্শ্ব-প্রতিক্রিয়া মুক্ত হওয়া উচিত। যখন আপনাকে একটি পার্শ্ব-প্রতিক্রিয়া সম্পাদন করতে হবে, এটি একটি কলব্যাক থেকে ট্রিগার করুন।
পুনর্গঠন আশাবাদী
যখনই কম্পোজ মনে করে যে একটি কম্পোজেবলের প্যারামিটারগুলি পরিবর্তিত হয়েছে তখনই পুনর্গঠন শুরু হয়। পুনর্গঠন আশাবাদী, যার মানে কম্পোজ আশা করে যে পরামিতিগুলি আবার পরিবর্তন করার আগে পুনর্গঠন শেষ হবে। পুনর্গঠন শেষ হওয়ার আগে যদি একটি প্যারামিটার পরিবর্তন হয় , তাহলে রচনাটি পুনর্গঠন বাতিল করে নতুন প্যারামিটার দিয়ে পুনরায় চালু করতে পারে।
যখন পুনর্গঠন বাতিল করা হয়, রচনা UI ট্রিকে পুনর্গঠন থেকে বাতিল করে। যদি আপনার কোন পার্শ্ব-প্রতিক্রিয়া থাকে যা UI প্রদর্শিত হচ্ছে তার উপর নির্ভর করে, তাহলে কম্পোজিশন বাতিল করা হলেও পার্শ্ব-প্রতিক্রিয়া প্রয়োগ করা হবে। এটি অসামঞ্জস্যপূর্ণ অ্যাপ্লিকেশন অবস্থা হতে পারে.
নিশ্চিত করুন যে সমস্ত সংমিশ্রণযোগ্য ফাংশন এবং ল্যাম্বডা আশাবাদী পুনর্গঠন পরিচালনা করার জন্য অদম্য এবং পার্শ্ব-প্রতিক্রিয়ামুক্ত।
কম্পোজযোগ্য ফাংশনগুলি প্রায়শই চলতে পারে
কিছু ক্ষেত্রে, UI অ্যানিমেশনের প্রতিটি ফ্রেমের জন্য একটি সংমিশ্রণযোগ্য ফাংশন চলতে পারে। যদি ফাংশনটি ব্যয়বহুল ক্রিয়াকলাপ সম্পাদন করে, যেমন ডিভাইস স্টোরেজ থেকে পড়া, ফাংশনটি UI জ্যাঙ্কের কারণ হতে পারে।
উদাহরণস্বরূপ, যদি আপনার উইজেট ডিভাইস সেটিংস পড়ার চেষ্টা করে, তাহলে এটি সম্ভাব্যভাবে সেকেন্ডে শত শত বার সেই সেটিংস পড়তে পারে, যা আপনার অ্যাপের কর্মক্ষমতার উপর বিপর্যয়কর প্রভাব ফেলতে পারে।
যদি আপনার সংমিশ্রণযোগ্য ফাংশনের ডেটার প্রয়োজন হয় তবে এটি ডেটার জন্য পরামিতিগুলি সংজ্ঞায়িত করবে। তারপরে আপনি ব্যয়বহুল কাজটিকে রচনার বাইরে অন্য থ্রেডে স্থানান্তর করতে পারেন এবং mutableStateOf
বা LiveData
ব্যবহার করে কম্পোজে ডেটা পাস করতে পারেন।
কম্পোজযোগ্য ফাংশন সমান্তরালভাবে চালানো যেতে পারে
কম্পোজ সমান্তরালভাবে কম্পোজযোগ্য ফাংশন চালানোর মাধ্যমে পুনর্গঠন অপ্টিমাইজ করতে পারে। এটি কম্পোজকে একাধিক কোরের সুবিধা নিতে দেয় এবং কম অগ্রাধিকারে স্ক্রীনে নয় কম্পোজযোগ্য ফাংশন চালাতে দেয়।
এই অপ্টিমাইজেশানের অর্থ হল একটি কম্পোজযোগ্য ফাংশন ব্যাকগ্রাউন্ড থ্রেডের পুলের মধ্যে কার্যকর হতে পারে। যদি একটি কম্পোজযোগ্য ফাংশন একটি ViewModel
এ একটি ফাংশনকে কল করে, কম্পোজ সেই ফাংশনটিকে একই সময়ে একাধিক থ্রেড থেকে কল করতে পারে।
আপনার অ্যাপ্লিকেশান সঠিকভাবে আচরণ করছে তা নিশ্চিত করতে, সমস্ত সংমিশ্রণযোগ্য ফাংশনগুলির কোনও পার্শ্ব-প্রতিক্রিয়া থাকা উচিত নয়। পরিবর্তে, কলব্যাক থেকে পার্শ্ব-প্রতিক্রিয়া ট্রিগার করুন যেমন onClick
যা সর্বদা UI থ্রেডে কার্যকর করে।
যখন একটি সংমিশ্রণযোগ্য ফাংশন আহ্বান করা হয়, কলারের থেকে একটি ভিন্ন থ্রেডে আমন্ত্রণ ঘটতে পারে। এর মানে হল যে কোডটি একটি কম্পোজেবল ল্যাম্বডাতে ভেরিয়েবলগুলিকে সংশোধন করে তা এড়িয়ে যাওয়া উচিত-উভয় কারণ এই ধরনের কোড থ্রেড-নিরাপদ নয় এবং কারণ এটি কম্পোজেবল ল্যাম্বডার একটি অননুমোদিত পার্শ্ব-প্রতিক্রিয়া।
এখানে একটি কম্পোজেবল দেখানো একটি উদাহরণ যা একটি তালিকা এবং এর সংখ্যা প্রদর্শন করে:
@Composable fun ListComposable(myList: List<String>) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") } } Text("Count: ${myList.size}") } }
এই কোডটি পার্শ্ব-প্রতিক্রিয়া মুক্ত, এবং ইনপুট তালিকাকে UI এ রূপান্তরিত করে। এটি একটি ছোট তালিকা প্রদর্শনের জন্য দুর্দান্ত কোড। যাইহোক, যদি ফাংশন একটি স্থানীয় ভেরিয়েবলে লিখে, এই কোড থ্রেড-নিরাপদ বা সঠিক হবে না:
@Composable fun ListWithBug(myList: List<String>) { var items = 0 Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Card { Text("Item: $item") items++ // Avoid! Side-effect of the column recomposing. } } } Text("Count: $items") } }
এই উদাহরণে, items
প্রতিটি পুনর্গঠন সঙ্গে সংশোধন করা হয়. এটি একটি অ্যানিমেশনের প্রতিটি ফ্রেম হতে পারে, বা যখন তালিকা আপডেট হয়। যেভাবেই হোক, UI ভুল গণনা প্রদর্শন করবে। এই কারণে, এই ধরনের লেখা কম্পোজে সমর্থিত নয়; এই লেখাগুলিকে নিষিদ্ধ করে, আমরা ফ্রেমওয়ার্ককে কম্পোজেবল ল্যাম্বডাস চালানোর জন্য থ্রেড পরিবর্তন করার অনুমতি দিই।
কম্পোজেবল ফাংশন যেকোন ক্রমে এক্সিকিউট করতে পারে
আপনি যদি একটি সংমিশ্রণযোগ্য ফাংশনের জন্য কোডটি দেখেন, তাহলে আপনি অনুমান করতে পারেন যে কোডটি যে ক্রমে প্রদর্শিত হবে সেই ক্রমে চালানো হয়েছে। কিন্তু এই সত্য হবে নিশ্চিত করা হয় না. যদি একটি সংমিশ্রণযোগ্য ফাংশনে অন্যান্য কম্পোজযোগ্য ফাংশনে কল থাকে, তবে সেই ফাংশনগুলি যে কোনও ক্রমে চলতে পারে। কম্পোজে কিছু UI উপাদান অন্যদের তুলনায় বেশি অগ্রাধিকার রয়েছে তা স্বীকার করার এবং প্রথমে সেগুলি আঁকার বিকল্প রয়েছে৷
উদাহরণস্বরূপ, ধরুন আপনার কাছে একটি ট্যাব লেআউটে তিনটি স্ক্রীন আঁকার জন্য এইরকম কোড আছে:
@Composable fun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() } }
StartScreen
, MiddleScreen
, এবং EndScreen
এ কলগুলি যেকোন ক্রমে ঘটতে পারে। এর মানে হল আপনি, উদাহরণস্বরূপ, StartScreen()
কে কিছু গ্লোবাল ভেরিয়েবল (একটি সাইড-ইফেক্ট) সেট করতে পারবেন না এবং MiddleScreen()
সেই পরিবর্তনের সুবিধা নিতে পারবেন। পরিবর্তে, সেই ফাংশনগুলির প্রতিটি স্বয়ংসম্পূর্ণ হওয়া দরকার।
আরও জানুন
কম্পোজ এবং কম্পোজযোগ্য ফাংশনে কীভাবে চিন্তা করতে হয় সে সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন।
ভিডিও
{% শব্দার্থে %}আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- জেটপ্যাক রচনার জন্য কোটলিন
- রাজ্য এবং জেটপ্যাক রচনা
- জেটপ্যাক কম্পোজ আর্কিটেকচারাল লেয়ারিং
জেটপ্যাক কম্পোজ অ্যান্ড্রয়েডের জন্য একটি আধুনিক ঘোষণামূলক UI টুলকিট। কম্পোজ একটি ঘোষণামূলক API প্রদান করে আপনার অ্যাপ UI লিখতে এবং বজায় রাখা সহজ করে তোলে যা আপনাকে ফ্রন্টএন্ড ভিউ মিউটেশন না করে আপনার অ্যাপ UI রেন্ডার করতে দেয়। এই পরিভাষাটির কিছু ব্যাখ্যা প্রয়োজন, কিন্তু প্রভাবগুলি আপনার অ্যাপ ডিজাইনের জন্য গুরুত্বপূর্ণ।
ঘোষণামূলক প্রোগ্রামিং দৃষ্টান্ত
ঐতিহাসিকভাবে, একটি অ্যান্ড্রয়েড ভিউ হায়ারার্কি UI উইজেটগুলির একটি ট্রি হিসাবে উপস্থাপনযোগ্য। ব্যবহারকারীর ইন্টারঅ্যাকশনের মতো জিনিসগুলির কারণে অ্যাপের অবস্থা পরিবর্তন হওয়ার কারণে, বর্তমান ডেটা প্রদর্শনের জন্য UI শ্রেণিবিন্যাস আপডেট করা প্রয়োজন। UI আপডেট করার সবচেয়ে সাধারণ উপায় হল findViewById()
মত ফাংশন ব্যবহার করে গাছে হাঁটা এবং button.setText(String)
, container.addChild(View)
বা img.setImageBitmap(Bitmap)
মত পদ্ধতিতে কল করে নোড পরিবর্তন করা। এই পদ্ধতিগুলি উইজেটের অভ্যন্তরীণ অবস্থা পরিবর্তন করে।
ম্যানুয়ালি ভিউ ম্যানিপুলেট করা ত্রুটির সম্ভাবনা বাড়ায়। যদি ডেটার একটি অংশ একাধিক জায়গায় রেন্ডার করা হয়, তবে এটি দেখায় এমন ভিউগুলির একটি আপডেট করতে ভুলে যাওয়া সহজ। অবৈধ রাষ্ট্র তৈরি করাও সহজ, যখন দুটি আপডেট একটি অপ্রত্যাশিত উপায়ে বিরোধিতা করে। উদাহরণস্বরূপ, একটি আপডেট একটি নোডের মান সেট করার চেষ্টা করতে পারে যা এইমাত্র UI থেকে সরানো হয়েছে। সাধারণভাবে, সফ্টওয়্যার রক্ষণাবেক্ষণের জটিলতা আপডেট করার প্রয়োজনের ভিউ সংখ্যার সাথে বৃদ্ধি পায়।
গত বেশ কয়েক বছর ধরে, পুরো শিল্পটি একটি ঘোষণামূলক UI মডেলে স্থানান্তরিত হতে শুরু করেছে, যা ব্যবহারকারীর ইন্টারফেস তৈরি এবং আপডেট করার সাথে যুক্ত ইঞ্জিনিয়ারিংকে ব্যাপকভাবে সরল করে। কৌশলটি ধারণাগতভাবে পুরো স্ক্রিনটিকে স্ক্র্যাচ থেকে পুনরুত্পাদন করে, তারপর শুধুমাত্র প্রয়োজনীয় পরিবর্তনগুলি প্রয়োগ করে কাজ করে। এই পদ্ধতিটি ম্যানুয়ালি একটি স্টেটফুল ভিউ হায়ারার্কি আপডেট করার জটিলতা এড়ায়। রচনা একটি ঘোষণামূলক UI ফ্রেমওয়ার্ক।
পুরো স্ক্রিন পুনরুত্থিত করার সাথে একটি চ্যালেঞ্জ হল এটি সম্ভাব্য ব্যয়বহুল, সময়, কম্পিউটিং শক্তি এবং ব্যাটারি ব্যবহারের ক্ষেত্রে। এই খরচ কমাতে, কম্পোজ বুদ্ধিমত্তার সাথে চয়ন করে যে UI-এর কোন অংশগুলি যেকোন সময়ে পুনরায় আঁকতে হবে। আপনি কীভাবে আপনার UI উপাদানগুলি ডিজাইন করেন তার জন্য এর কিছু প্রভাব রয়েছে, যেমন Recomposition এ আলোচনা করা হয়েছে।
একটি সহজ কম্পোজযোগ্য ফাংশন
রচনা ব্যবহার করে, আপনি কম্পোজযোগ্য ফাংশনগুলির একটি সেট সংজ্ঞায়িত করে আপনার ব্যবহারকারী ইন্টারফেস তৈরি করতে পারেন যা ডেটা গ্রহণ করে এবং UI উপাদানগুলি নির্গত করে। একটি সাধারণ উদাহরণ হল একটি Greeting
উইজেট, যা একটি String
নেয় এবং একটি Text
উইজেট নির্গত করে যা একটি শুভেচ্ছা বার্তা প্রদর্শন করে।
চিত্র 1. একটি সাধারণ সংমিশ্রণযোগ্য ফাংশন যা ডেটা পাস করে এবং এটি পর্দায় একটি পাঠ্য উইজেট রেন্ডার করতে ব্যবহার করে।
এই ফাংশন সম্পর্কে কয়েকটি উল্লেখযোগ্য বিষয়:
ফাংশনটি
@Composable
টীকা দিয়ে টীকা করা হয়েছে। সমস্ত কম্পোজযোগ্য ফাংশনে এই টীকা থাকতে হবে; এই টীকাটি কম্পোজ কম্পাইলারকে জানায় যে এই ফাংশনটি ডেটাকে UI-তে রূপান্তর করার উদ্দেশ্যে।ফাংশন ডেটা নেয়। কম্পোজেবল ফাংশন পরামিতি গ্রহণ করতে পারে, যা অ্যাপ লজিককে UI বর্ণনা করতে দেয়। এই ক্ষেত্রে, আমাদের উইজেট একটি
String
গ্রহণ করে যাতে এটি নাম দ্বারা ব্যবহারকারীকে অভিবাদন জানাতে পারে।ফাংশনটি UI-তে পাঠ্য প্রদর্শন করে। এটি
Text()
কম্পোজেবল ফাংশনকে কল করে তা করে, যা আসলে টেক্সট UI উপাদান তৈরি করে। কম্পোজযোগ্য ফাংশনগুলি অন্যান্য কম্পোজেবল ফাংশনগুলিকে কল করে UI অনুক্রম নির্গত করে।ফাংশন কিছু ফেরত না. যে ফাংশনগুলি UI নির্গত করে তাদের কিছু ফেরত দেওয়ার দরকার নেই, কারণ তারা UI উইজেটগুলি তৈরি করার পরিবর্তে পছন্দসই স্ক্রীনের অবস্থা বর্ণনা করে।
এই ফাংশনটি দ্রুত, অদম্য এবং পার্শ্বপ্রতিক্রিয়ামুক্ত ।
- একই আর্গুমেন্টের সাথে একাধিকবার কল করা হলে ফাংশনটি একইভাবে আচরণ করে এবং এটি গ্লোবাল ভেরিয়েবল বা
random()
তে কল করার মতো অন্যান্য মান ব্যবহার করে না। - ফাংশনটি কোনো পার্শ্ব-প্রতিক্রিয়া ছাড়াই UI বর্ণনা করে, যেমন বৈশিষ্ট্য পরিবর্তন করা বা গ্লোবাল ভেরিয়েবল।
সাধারণভাবে, সমস্ত সংমিশ্রণযোগ্য ফাংশনগুলিকে এই বৈশিষ্ট্যগুলির সাথে লিখতে হবে, কারণগুলি পুনর্গঠনে আলোচনা করা হয়েছে।
- একই আর্গুমেন্টের সাথে একাধিকবার কল করা হলে ফাংশনটি একইভাবে আচরণ করে এবং এটি গ্লোবাল ভেরিয়েবল বা
ঘোষণামূলক প্যারাডাইম শিফট
অনেক প্রয়োজনীয় অবজেক্ট-ওরিয়েন্টেড UI টুলকিট সহ, আপনি উইজেটের একটি ট্রি ইনস্ট্যান্টিয়েট করে UI আরম্ভ করেন। আপনি প্রায়শই একটি XML লেআউট ফাইল স্ফীত করে এটি করেন। প্রতিটি উইজেট তার নিজস্ব অভ্যন্তরীণ অবস্থা বজায় রাখে এবং গেটার এবং সেটার পদ্ধতিগুলিকে প্রকাশ করে যা অ্যাপ লজিককে উইজেটের সাথে ইন্টারঅ্যাক্ট করার অনুমতি দেয়।
রচনার ঘোষণামূলক পদ্ধতিতে, উইজেটগুলি তুলনামূলকভাবে রাষ্ট্রহীন এবং সেটার বা গেটার ফাংশন প্রকাশ করে না। আসলে, উইজেটগুলি বস্তু হিসাবে উন্মুক্ত হয় না। আপনি বিভিন্ন আর্গুমেন্ট সহ একই কম্পোজেবল ফাংশন কল করে UI আপডেট করেন। এটি একটি ViewModel
মতো আর্কিটেকচারাল প্যাটার্নে স্টেট প্রদান করা সহজ করে তোলে, যেমনটি অ্যাপ আর্কিটেকচারের গাইডে বর্ণিত হয়েছে। তারপর, আপনার কম্পোজেবলগুলি প্রতিবার পর্যবেক্ষণযোগ্য ডেটা আপডেট হওয়ার সময় বর্তমান অ্যাপ্লিকেশন অবস্থাকে একটি UI-তে রূপান্তর করার জন্য দায়ী।
চিত্র 2. অ্যাপ লজিক টপ-লেভেল কম্পোজেবল ফাংশনে ডেটা প্রদান করে। এই ফাংশনটি অন্যান্য কম্পোজেবলকে কল করে UI বর্ণনা করতে ডেটা ব্যবহার করে এবং সেই কম্পোজেবলগুলিতে এবং অনুক্রমের নিচে যথাযথ ডেটা পাঠায়।
ব্যবহারকারী যখন UI এর সাথে ইন্টারঅ্যাক্ট করে, তখন UI ইভেন্ট উত্থাপন করে যেমন onClick
। সেই ইভেন্টগুলি অ্যাপের যুক্তিকে অবহিত করা উচিত, যা তারপরে অ্যাপের অবস্থা পরিবর্তন করতে পারে। যখন অবস্থা পরিবর্তিত হয়, তখন কম্পোজযোগ্য ফাংশনগুলিকে নতুন ডেটা সহ আবার কল করা হয়। এটি UI উপাদানগুলিকে পুনরায় আঁকার কারণ করে--এই প্রক্রিয়াটিকে পুনর্গঠন বলা হয়।
চিত্র 3. ব্যবহারকারী একটি UI উপাদানের সাথে ইন্টারঅ্যাক্ট করেছে, যার ফলে একটি ইভেন্ট ট্রিগার হয়েছে৷ অ্যাপ লজিক ইভেন্টে সাড়া দেয়, তারপর প্রয়োজন হলে কম্পোজেবল ফাংশনগুলি স্বয়ংক্রিয়ভাবে নতুন প্যারামিটার সহ আবার কল করা হয়।
গতিশীল বিষয়বস্তু
যেহেতু কম্পোজেবল ফাংশনগুলি XML-এর পরিবর্তে Kotlin-এ লেখা হয়, সেগুলি অন্য কোটলিন কোডের মতোই গতিশীল হতে পারে। উদাহরণস্বরূপ, ধরুন আপনি একটি UI তৈরি করতে চান যা ব্যবহারকারীদের একটি তালিকাকে শুভেচ্ছা জানায়:
@Composable fun Greeting(names: List<String>) { for (name in names) { Text("Hello $name") } }
এই ফাংশনটি নামের একটি তালিকা নেয় এবং প্রতিটি ব্যবহারকারীর জন্য একটি অভিবাদন তৈরি করে। কম্পোজযোগ্য ফাংশন বেশ পরিশীলিত হতে পারে। আপনি একটি নির্দিষ্ট UI উপাদান দেখাতে চান কিনা তা নির্ধারণ করতে আপনি if
বিবৃতি ব্যবহার করতে পারেন। আপনি loops ব্যবহার করতে পারেন. আপনি সহায়ক ফাংশন কল করতে পারেন. আপনার অন্তর্নিহিত ভাষার সম্পূর্ণ নমনীয়তা আছে। এই শক্তি এবং নমনীয়তা জেটপ্যাক রচনার অন্যতম প্রধান সুবিধা।
পুনর্গঠন
একটি বাধ্যতামূলক UI মডেলে, একটি উইজেট পরিবর্তন করতে, আপনি উইজেটের অভ্যন্তরীণ অবস্থা পরিবর্তন করতে একটি সেটারকে কল করেন। কম্পোজে, আপনি নতুন ডেটা সহ কম্পোজযোগ্য ফাংশনটিকে আবার কল করুন। এটি করার ফলে ফাংশনটি পুনরায় কম্পোজ করা হয় -- ফাংশন দ্বারা নির্গত উইজেটগুলি নতুন ডেটা সহ প্রয়োজনে পুনরায় আঁকা হয়। কম্পোজ ফ্রেমওয়ার্ক বুদ্ধিমত্তার সাথে শুধুমাত্র পরিবর্তিত উপাদানগুলিকে পুনরায় কম্পোজ করতে পারে।
উদাহরণস্বরূপ, এই সংমিশ্রণযোগ্য ফাংশনটি বিবেচনা করুন যা একটি বোতাম প্রদর্শন করে:
@Composable fun ClickCounter(clicks: Int, onClick: () -> Unit) { Button(onClick = onClick) { Text("I've been clicked $clicks times") } }
প্রতিবার বোতামটি ক্লিক করা হলে, কলার clicks
মান আপডেট করে। কম্পোজ নতুন মান দেখানোর জন্য আবার Text
ফাংশন সহ ল্যাম্বডাকে কল করে; এই প্রক্রিয়াটিকে বলা হয় পুনর্গঠন । অন্যান্য ফাংশন যা মানের উপর নির্ভর করে না সেগুলি পুনর্গঠিত হয় না।
যেমনটি আমরা আলোচনা করেছি, সমগ্র UI ট্রি পুনরায় কম্পোজ করা গণনাগতভাবে ব্যয়বহুল হতে পারে, যা কম্পিউটিং শক্তি এবং ব্যাটারি লাইফ ব্যবহার করে। রচনা এই বুদ্ধিমান পুনর্গঠনের সাথে এই সমস্যার সমাধান করে।
পুনর্গঠন হল ইনপুট পরিবর্তন হলে আপনার কম্পোজযোগ্য ফাংশনগুলিকে আবার কল করার প্রক্রিয়া। এটি ঘটে যখন ফাংশনের ইনপুট পরিবর্তন হয়। যখন কম্পোজ নতুন ইনপুটগুলির উপর ভিত্তি করে পুনর্গঠন করা হয়, তখন এটি শুধুমাত্র সেই ফাংশন বা ল্যাম্বডাসগুলিকে কল করে যা পরিবর্তিত হতে পারে এবং বাকিগুলি এড়িয়ে যায়। পরিবর্তিত প্যারামিটার নেই এমন সমস্ত ফাংশন বা ল্যাম্বডাস বাদ দিয়ে, রচনা দক্ষতার সাথে পুনরায় রচনা করতে পারে।
সংমিশ্রণযোগ্য ফাংশনগুলি কার্যকর করার পার্শ্ব-প্রতিক্রিয়াগুলির উপর নির্ভর করবেন না, যেহেতু একটি ফাংশনের পুনর্গঠন এড়িয়ে যেতে পারে। যদি আপনি তা করেন, ব্যবহারকারীরা আপনার অ্যাপে অদ্ভুত এবং অপ্রত্যাশিত আচরণ অনুভব করতে পারে। একটি পার্শ্ব-প্রতিক্রিয়া হল যেকোনো পরিবর্তন যা আপনার বাকি অ্যাপে দৃশ্যমান। উদাহরণস্বরূপ, এই ক্রিয়াগুলি সমস্ত বিপজ্জনক পার্শ্ব প্রতিক্রিয়া:
- একটি ভাগ করা বস্তুর একটি সম্পত্তি লেখা
-
ViewModel
এ একটি পর্যবেক্ষণযোগ্য আপডেট করা হচ্ছে - ভাগ করা পছন্দ আপডেট করা হচ্ছে
কম্পোজেবল ফাংশনগুলি প্রতি ফ্রেমের মতো প্রায়ই পুনঃনির্বাহিত হতে পারে, যেমন যখন একটি অ্যানিমেশন রেন্ডার করা হচ্ছে। অ্যানিমেশনের সময় জ্যাঙ্ক এড়াতে কম্পোজযোগ্য ফাংশনগুলি দ্রুত হওয়া উচিত। আপনার যদি ব্যয়বহুল ক্রিয়াকলাপগুলি করতে হয়, যেমন ভাগ করা পছন্দগুলি থেকে পড়া, এটি একটি ব্যাকগ্রাউন্ড কোরোটিনে করুন এবং মান ফলাফলটিকে একটি প্যারামিটার হিসাবে কম্পোজেবল ফাংশনে পাস করুন৷
একটি উদাহরণ হিসাবে, এই কোডটি SharedPreferences
এ একটি মান আপডেট করার জন্য একটি রচনাযোগ্য তৈরি করে। কম্পোজেবল শেয়ার করা পছন্দ থেকে পড়া বা লেখা উচিত নয়। পরিবর্তে, এই কোডটি পঠন এবং লেখাকে একটি পটভূমি কোরোটিনে একটি ViewModel
নিয়ে যায়। অ্যাপ লজিক একটি আপডেট ট্রিগার করতে একটি কলব্যাক সহ বর্তমান মান পাস করে।
@Composable fun SharedPrefsToggle( text: String, value: Boolean, onValueChanged: (Boolean) -> Unit ) { Row { Text(text) Checkbox(checked = value, onCheckedChange = onValueChanged) } }
আপনি যখন রচনা ব্যবহার করেন তখন এই দস্তাবেজটি বেশ কয়েকটি বিষয় নিয়ে আলোচনা করে:
- পুনর্গঠন যতটা সম্ভব কম্পোজেবল ফাংশন এবং ল্যাম্বডাস এড়িয়ে যায়।
- পুনর্গঠন আশাবাদী এবং বাতিল হতে পারে।
- একটি সংমিশ্রণযোগ্য ফাংশন বেশ ঘন ঘন চালানো হতে পারে, যেমন প্রায়শই একটি অ্যানিমেশনের প্রতিটি ফ্রেম।
- কম্পোজযোগ্য ফাংশন সমান্তরালভাবে কার্যকর করতে পারে।
- কম্পোজেবল ফাংশন যেকোন ক্রমে এক্সিকিউট করতে পারে।
নিম্নলিখিত বিভাগগুলি পুনর্গঠন সমর্থন করার জন্য কম্পোজযোগ্য ফাংশনগুলি কীভাবে তৈরি করা যায় তা কভার করবে। প্রতিটি ক্ষেত্রে, সর্বোত্তম অনুশীলন হল আপনার কম্পোজেবল ফাংশনগুলিকে দ্রুত, অদম্য এবং পার্শ্ব-প্রতিক্রিয়া মুক্ত রাখা।
পুনর্গঠন যতটা সম্ভব এড়িয়ে যায়
যখন আপনার UI-এর অংশগুলি অবৈধ হয়, তখন কম্পোজ সেই অংশগুলিকে পুনরায় কম্পোজ করার জন্য সর্বোত্তম চেষ্টা করে যা আপডেট করা দরকার৷ এর মানে হল এটি UI ট্রিতে উপরে বা নীচের কোনো কম্পোজেবল এক্সিকিউট না করে একটি একক বোতামের কম্পোজেবল পুনরায় চালানোর জন্য এড়িয়ে যেতে পারে।
প্রতিটি সংমিশ্রণযোগ্য ফাংশন এবং ল্যাম্বডা নিজেই পুনরায় সংমিশ্রণ করতে পারে। এখানে একটি উদাহরণ রয়েছে যা প্রদর্শন করে যে কীভাবে একটি তালিকা রেন্ডার করার সময় পুনর্গঠন কিছু উপাদান এড়িয়ে যেতে পারে:
/** * Display a list of names the user can click with a header */ @Composable fun NamePicker( header: String, names: List<String>, onNameClicked: (String) -> Unit ) { Column { // this will recompose when [header] changes, but not when [names] changes Text(header, style = MaterialTheme.typography.bodyLarge) HorizontalDivider() // LazyColumn is the Compose version of a RecyclerView. // The lambda passed to items() is similar to a RecyclerView.ViewHolder. LazyColumn { items(names) { name -> // When an item's [name] updates, the adapter for that item // will recompose. This will not recompose when [header] changes NamePickerItem(name, onNameClicked) } } } } /** * Display a single name the user can click. */ @Composable private fun NamePickerItem(name: String, onClicked: (String) -> Unit) { Text(name, Modifier.clickable(onClick = { onClicked(name) })) }
এই স্কোপগুলির প্রতিটি একটি পুনর্গঠনের সময় চালানোর একমাত্র জিনিস হতে পারে। header
পরিবর্তিত হলে কম্পোজ তার পিতামাতার কাউকে কার্যকর না করেই Column
ল্যাম্বডায় চলে যেতে পারে। এবং Column
চালানোর সময়, names
পরিবর্তন না হলে রচনা LazyColumn
এর আইটেমগুলি এড়িয়ে যেতে পারে।
আবার, সমস্ত সংমিশ্রণযোগ্য ফাংশন বা ল্যাম্বডাস সম্পাদন করা পার্শ্ব-প্রতিক্রিয়া মুক্ত হওয়া উচিত। যখন আপনাকে একটি পার্শ্ব-প্রতিক্রিয়া সম্পাদন করতে হবে, এটি একটি কলব্যাক থেকে ট্রিগার করুন।
পুনর্গঠন আশাবাদী
যখনই কম্পোজ মনে করে যে একটি কম্পোজেবলের প্যারামিটারগুলি পরিবর্তিত হয়েছে তখনই পুনর্গঠন শুরু হয়। পুনর্গঠন আশাবাদী, যার মানে কম্পোজ আশা করে যে পরামিতিগুলি আবার পরিবর্তন করার আগে পুনর্গঠন শেষ হবে। পুনর্গঠন শেষ হওয়ার আগে যদি একটি প্যারামিটার পরিবর্তন হয় , তাহলে রচনাটি পুনর্গঠন বাতিল করে নতুন প্যারামিটার দিয়ে পুনরায় চালু করতে পারে।
যখন পুনর্গঠন বাতিল করা হয়, রচনা UI ট্রিকে পুনর্গঠন থেকে বাতিল করে। যদি আপনার কোন পার্শ্ব-প্রতিক্রিয়া থাকে যা UI প্রদর্শিত হচ্ছে তার উপর নির্ভর করে, তাহলে কম্পোজিশন বাতিল করা হলেও পার্শ্ব-প্রতিক্রিয়া প্রয়োগ করা হবে। এটি অসামঞ্জস্যপূর্ণ অ্যাপ্লিকেশন অবস্থা হতে পারে.
নিশ্চিত করুন যে সমস্ত সংমিশ্রণযোগ্য ফাংশন এবং ল্যাম্বডা আশাবাদী পুনর্গঠন পরিচালনা করার জন্য অদম্য এবং পার্শ্ব-প্রতিক্রিয়ামুক্ত।
কম্পোজযোগ্য ফাংশনগুলি প্রায়শই চলতে পারে
কিছু ক্ষেত্রে, UI অ্যানিমেশনের প্রতিটি ফ্রেমের জন্য একটি সংমিশ্রণযোগ্য ফাংশন চলতে পারে। যদি ফাংশনটি ব্যয়বহুল ক্রিয়াকলাপ সম্পাদন করে, যেমন ডিভাইস স্টোরেজ থেকে পড়া, ফাংশনটি UI জ্যাঙ্কের কারণ হতে পারে।
উদাহরণস্বরূপ, যদি আপনার উইজেট ডিভাইস সেটিংস পড়ার চেষ্টা করে, তাহলে এটি সম্ভাব্যভাবে সেকেন্ডে শত শত বার সেই সেটিংস পড়তে পারে, যা আপনার অ্যাপের কর্মক্ষমতার উপর বিপর্যয়কর প্রভাব ফেলতে পারে।
যদি আপনার সংমিশ্রণযোগ্য ফাংশনের ডেটার প্রয়োজন হয় তবে এটি ডেটার জন্য পরামিতিগুলি সংজ্ঞায়িত করবে। তারপরে আপনি ব্যয়বহুল কাজটিকে রচনার বাইরে অন্য থ্রেডে স্থানান্তর করতে পারেন এবং mutableStateOf
বা LiveData
ব্যবহার করে কম্পোজে ডেটা পাস করতে পারেন।
কম্পোজযোগ্য ফাংশন সমান্তরালভাবে চালানো যেতে পারে
কম্পোজ সমান্তরালভাবে কম্পোজযোগ্য ফাংশন চালানোর মাধ্যমে পুনর্গঠন অপ্টিমাইজ করতে পারে। এটি কম্পোজকে একাধিক কোরের সুবিধা নিতে দেয় এবং কম অগ্রাধিকারে স্ক্রীনে নয় কম্পোজযোগ্য ফাংশন চালাতে দেয়।
এই অপ্টিমাইজেশানের অর্থ হল একটি কম্পোজযোগ্য ফাংশন ব্যাকগ্রাউন্ড থ্রেডের পুলের মধ্যে কার্যকর হতে পারে। যদি একটি কম্পোজযোগ্য ফাংশন একটি ViewModel
এ একটি ফাংশনকে কল করে, কম্পোজ সেই ফাংশনটিকে একই সময়ে একাধিক থ্রেড থেকে কল করতে পারে।
আপনার অ্যাপ্লিকেশান সঠিকভাবে আচরণ করছে তা নিশ্চিত করতে, সমস্ত সংমিশ্রণযোগ্য ফাংশনগুলির কোনও পার্শ্ব-প্রতিক্রিয়া থাকা উচিত নয়। পরিবর্তে, কলব্যাক থেকে পার্শ্ব-প্রতিক্রিয়া ট্রিগার করুন যেমন onClick
যা সর্বদা UI থ্রেডে কার্যকর করে।
যখন একটি সংমিশ্রণযোগ্য ফাংশন আহ্বান করা হয়, কলারের থেকে একটি ভিন্ন থ্রেডে আমন্ত্রণ ঘটতে পারে। এর মানে হল যে কোডটি একটি কম্পোজেবল ল্যাম্বডাতে ভেরিয়েবলগুলিকে সংশোধন করে তা এড়িয়ে যাওয়া উচিত-উভয় কারণ এই ধরনের কোড থ্রেড-নিরাপদ নয় এবং কারণ এটি কম্পোজেবল ল্যাম্বডার একটি অননুমোদিত পার্শ্ব-প্রতিক্রিয়া।
এখানে একটি কম্পোজেবল দেখানো একটি উদাহরণ যা একটি তালিকা এবং এর সংখ্যা প্রদর্শন করে:
@Composable fun ListComposable(myList: List<String>) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") } } Text("Count: ${myList.size}") } }
এই কোডটি পার্শ্ব-প্রতিক্রিয়া মুক্ত, এবং ইনপুট তালিকাকে UI এ রূপান্তরিত করে। এটি একটি ছোট তালিকা প্রদর্শনের জন্য দুর্দান্ত কোড। যাইহোক, যদি ফাংশন একটি স্থানীয় ভেরিয়েবলে লিখে, এই কোড থ্রেড-নিরাপদ বা সঠিক হবে না:
@Composable fun ListWithBug(myList: List<String>) { var items = 0 Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Card { Text("Item: $item") items++ // Avoid! Side-effect of the column recomposing. } } } Text("Count: $items") } }
এই উদাহরণে, items
প্রতিটি পুনর্গঠন সঙ্গে সংশোধন করা হয়. এটি একটি অ্যানিমেশনের প্রতিটি ফ্রেম হতে পারে, বা যখন তালিকা আপডেট হয়। যেভাবেই হোক, UI ভুল গণনা প্রদর্শন করবে। এই কারণে, এই ধরনের লেখা কম্পোজে সমর্থিত নয়; এই লেখাগুলিকে নিষিদ্ধ করে, আমরা ফ্রেমওয়ার্ককে কম্পোজেবল ল্যাম্বডাস চালানোর জন্য থ্রেড পরিবর্তন করার অনুমতি দিই।
কম্পোজেবল ফাংশন যেকোন ক্রমে এক্সিকিউট করতে পারে
আপনি যদি একটি সংমিশ্রণযোগ্য ফাংশনের জন্য কোডটি দেখেন, তাহলে আপনি অনুমান করতে পারেন যে কোডটি যে ক্রমে প্রদর্শিত হবে সেই ক্রমে চালানো হয়েছে। কিন্তু এই সত্য হবে নিশ্চিত করা হয় না. যদি একটি সংমিশ্রণযোগ্য ফাংশনে অন্যান্য কম্পোজযোগ্য ফাংশনে কল থাকে, তবে সেই ফাংশনগুলি যে কোনও ক্রমে চলতে পারে। কম্পোজে কিছু UI উপাদান অন্যদের তুলনায় বেশি অগ্রাধিকার রয়েছে তা স্বীকার করার এবং প্রথমে সেগুলি আঁকার বিকল্প রয়েছে৷
উদাহরণস্বরূপ, ধরুন আপনার কাছে একটি ট্যাব লেআউটে তিনটি স্ক্রীন আঁকার জন্য এইরকম কোড আছে:
@Composable fun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() } }
StartScreen
, MiddleScreen
, এবং EndScreen
এ কলগুলি যেকোন ক্রমে ঘটতে পারে। এর মানে হল আপনি, উদাহরণস্বরূপ, StartScreen()
কে কিছু গ্লোবাল ভেরিয়েবল (একটি সাইড-ইফেক্ট) সেট করতে পারবেন না এবং MiddleScreen()
সেই পরিবর্তনের সুবিধা নিতে পারবেন। পরিবর্তে, সেই ফাংশনগুলির প্রতিটি স্বয়ংসম্পূর্ণ হওয়া দরকার।
আরও জানুন
কম্পোজ এবং কম্পোজযোগ্য ফাংশনে কীভাবে চিন্তা করতে হয় সে সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন।
ভিডিও
{% শব্দার্থে %}আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- জেটপ্যাক রচনার জন্য কোটলিন
- রাজ্য এবং জেটপ্যাক রচনা
- জেটপ্যাক কম্পোজ আর্কিটেকচারাল লেয়ারিং
জেটপ্যাক কম্পোজ অ্যান্ড্রয়েডের জন্য একটি আধুনিক ঘোষণামূলক UI টুলকিট। কম্পোজ একটি ঘোষণামূলক API প্রদান করে আপনার অ্যাপ UI লিখতে এবং বজায় রাখা সহজ করে তোলে যা আপনাকে ফ্রন্টএন্ড ভিউ মিউটেশন না করে আপনার অ্যাপ UI রেন্ডার করতে দেয়। এই পরিভাষাটির কিছু ব্যাখ্যা প্রয়োজন, তবে প্রভাবগুলি আপনার অ্যাপ ডিজাইনের জন্য গুরুত্বপূর্ণ।
ঘোষণামূলক প্রোগ্রামিং দৃষ্টান্ত
ঐতিহাসিকভাবে, একটি অ্যান্ড্রয়েড ভিউ হায়ারার্কি UI উইজেটগুলির একটি ট্রি হিসাবে উপস্থাপনযোগ্য। ব্যবহারকারীর ইন্টারঅ্যাকশনের মতো জিনিসগুলির কারণে অ্যাপের অবস্থা পরিবর্তন হওয়ার কারণে, বর্তমান ডেটা প্রদর্শনের জন্য UI শ্রেণিবিন্যাস আপডেট করা প্রয়োজন। UI আপডেট করার সবচেয়ে সাধারণ উপায় হল findViewById()
মত ফাংশন ব্যবহার করে গাছে হাঁটা এবং button.setText(String)
, container.addChild(View)
বা img.setImageBitmap(Bitmap)
মত পদ্ধতিতে কল করে নোড পরিবর্তন করা। এই পদ্ধতিগুলি উইজেটের অভ্যন্তরীণ অবস্থা পরিবর্তন করে।
ম্যানুয়ালি ভিউ ম্যানিপুলেট করা ত্রুটির সম্ভাবনা বাড়ায়। যদি ডেটার একটি অংশ একাধিক জায়গায় রেন্ডার করা হয়, তবে এটি দেখায় এমন ভিউগুলির একটি আপডেট করতে ভুলে যাওয়া সহজ। অবৈধ রাষ্ট্র তৈরি করাও সহজ, যখন দুটি আপডেট একটি অপ্রত্যাশিত উপায়ে বিরোধিতা করে। উদাহরণস্বরূপ, একটি আপডেট একটি নোডের মান সেট করার চেষ্টা করতে পারে যা এইমাত্র UI থেকে সরানো হয়েছে। সাধারণভাবে, সফ্টওয়্যার রক্ষণাবেক্ষণের জটিলতা আপডেট করার প্রয়োজনের ভিউ সংখ্যার সাথে বৃদ্ধি পায়।
গত বেশ কয়েক বছর ধরে, পুরো শিল্পটি একটি ঘোষণামূলক UI মডেলে স্থানান্তরিত হতে শুরু করেছে, যা ব্যবহারকারীর ইন্টারফেস তৈরি এবং আপডেট করার সাথে যুক্ত ইঞ্জিনিয়ারিংকে ব্যাপকভাবে সরল করে। কৌশলটি ধারণাগতভাবে পুরো স্ক্রিনটিকে স্ক্র্যাচ থেকে পুনরুত্পাদন করে, তারপর শুধুমাত্র প্রয়োজনীয় পরিবর্তনগুলি প্রয়োগ করে কাজ করে। এই পদ্ধতিটি ম্যানুয়ালি একটি স্টেটফুল ভিউ হায়ারার্কি আপডেট করার জটিলতা এড়ায়। রচনা একটি ঘোষণামূলক UI ফ্রেমওয়ার্ক।
পুরো স্ক্রিন পুনরুত্থিত করার সাথে একটি চ্যালেঞ্জ হল এটি সম্ভাব্য ব্যয়বহুল, সময়, কম্পিউটিং শক্তি এবং ব্যাটারি ব্যবহারের ক্ষেত্রে। এই খরচ কমাতে, কম্পোজ বুদ্ধিমত্তার সাথে চয়ন করে যে UI-এর কোন অংশগুলি যেকোন সময়ে পুনরায় আঁকতে হবে। আপনি কীভাবে আপনার UI উপাদানগুলি ডিজাইন করেন তার জন্য এর কিছু প্রভাব রয়েছে, যেমন Recomposition এ আলোচনা করা হয়েছে।
একটি সহজ কম্পোজযোগ্য ফাংশন
রচনা ব্যবহার করে, আপনি কম্পোজযোগ্য ফাংশনগুলির একটি সেট সংজ্ঞায়িত করে আপনার ব্যবহারকারী ইন্টারফেস তৈরি করতে পারেন যা ডেটা গ্রহণ করে এবং UI উপাদানগুলি নির্গত করে। একটি সাধারণ উদাহরণ হল একটি Greeting
উইজেট, যা একটি String
নেয় এবং একটি Text
উইজেট নির্গত করে যা একটি শুভেচ্ছা বার্তা প্রদর্শন করে।
চিত্র 1. একটি সাধারণ সংমিশ্রণযোগ্য ফাংশন যা ডেটা পাস করে এবং এটি পর্দায় একটি পাঠ্য উইজেট রেন্ডার করতে ব্যবহার করে।
এই ফাংশন সম্পর্কে কয়েকটি উল্লেখযোগ্য বিষয়:
ফাংশনটি
@Composable
টীকা দিয়ে টীকা করা হয়েছে। সমস্ত কম্পোজযোগ্য ফাংশনে এই টীকা থাকতে হবে; এই টীকাটি কম্পোজ কম্পাইলারকে জানায় যে এই ফাংশনটি ডেটাকে UI-তে রূপান্তর করার উদ্দেশ্যে।ফাংশন ডেটা নেয়। কম্পোজেবল ফাংশন পরামিতি গ্রহণ করতে পারে, যা অ্যাপ লজিককে UI বর্ণনা করতে দেয়। এই ক্ষেত্রে, আমাদের উইজেট একটি
String
গ্রহণ করে যাতে এটি নাম দ্বারা ব্যবহারকারীকে অভিবাদন জানাতে পারে।ফাংশনটি UI-তে পাঠ্য প্রদর্শন করে। এটি
Text()
কম্পোজেবল ফাংশনকে কল করে তা করে, যা আসলে টেক্সট UI উপাদান তৈরি করে। কম্পোজযোগ্য ফাংশনগুলি অন্যান্য কম্পোজেবল ফাংশনগুলিকে কল করে UI অনুক্রম নির্গত করে।ফাংশন কিছু ফেরত না. যে ফাংশনগুলি UI নির্গত করে তাদের কিছু ফেরত দেওয়ার দরকার নেই, কারণ তারা UI উইজেটগুলি তৈরি করার পরিবর্তে পছন্দসই স্ক্রীনের অবস্থা বর্ণনা করে।
এই ফাংশনটি দ্রুত, অদম্য এবং পার্শ্বপ্রতিক্রিয়ামুক্ত ।
- একই আর্গুমেন্টের সাথে একাধিকবার কল করা হলে ফাংশনটি একইভাবে আচরণ করে এবং এটি গ্লোবাল ভেরিয়েবল বা
random()
তে কল করার মতো অন্যান্য মান ব্যবহার করে না। - ফাংশনটি কোনো পার্শ্ব-প্রতিক্রিয়া ছাড়াই UI বর্ণনা করে, যেমন বৈশিষ্ট্য পরিবর্তন করা বা গ্লোবাল ভেরিয়েবল।
সাধারণভাবে, সমস্ত কমপোজেবল ফাংশনগুলি এই বৈশিষ্ট্যগুলির সাথে লিখিত হওয়া উচিত, পুনরুদ্ধারগুলিতে আলোচিত কারণগুলির জন্য।
- একই আর্গুমেন্টের সাথে একাধিকবার কল করা হলে ফাংশনটি একইভাবে আচরণ করে এবং এটি গ্লোবাল ভেরিয়েবল বা
ঘোষণামূলক দৃষ্টান্তের শিফট
অনেক অপরিহার্য অবজেক্ট-ভিত্তিক ইউআই টুলকিটগুলির সাথে, আপনি উইজেটগুলির একটি গাছ ইনস্ট্যান্ট করে ইউআই আরম্ভ করেন। আপনি প্রায়শই একটি এক্সএমএল লেআউট ফাইলটি স্ফীত করে এটি করেন। প্রতিটি উইজেট তার নিজস্ব অভ্যন্তরীণ অবস্থা বজায় রাখে এবং গেটর এবং সেটার পদ্ধতিগুলি প্রকাশ করে যা অ্যাপ্লিকেশন যুক্তিটিকে উইজেটের সাথে ইন্টারঅ্যাক্ট করতে দেয়।
কমপোজের ঘোষণামূলক পদ্ধতিতে, উইজেটগুলি তুলনামূলকভাবে রাষ্ট্রহীন এবং সেটার বা গেটার ফাংশনগুলি প্রকাশ করবেন না। আসলে, উইজেটগুলি বস্তু হিসাবে প্রকাশিত হয় না। আপনি বিভিন্ন আর্গুমেন্টের সাথে একই কম্পোজেবল ফাংশনটি কল করে ইউআই আপডেট করুন। এটি অ্যাপ্লিকেশন আর্কিটেকচারের গাইডে বর্ণিত হিসাবে ViewModel
মতো স্থাপত্য নিদর্শনগুলিকে রাষ্ট্র সরবরাহ করা সহজ করে তোলে। তারপরে, আপনার কমপোজেবলগুলি পর্যবেক্ষণযোগ্য ডেটা আপডেটগুলি প্রতিবার কোনও ইউআই -তে রূপান্তর করার জন্য দায়বদ্ধ।
চিত্র 2। অ্যাপ লজিক শীর্ষ-স্তরের কমপোজেবল ফাংশনে ডেটা সরবরাহ করে। এই ফাংশনটি অন্যান্য কমপোজেবলগুলি কল করে ইউআইকে বর্ণনা করতে ডেটা ব্যবহার করে এবং সেই কম্পোজেবলগুলিতে উপযুক্ত ডেটা এবং হায়ারার্কির নীচে পাস করে।
যখন ব্যবহারকারী ইউআইয়ের সাথে যোগাযোগ করে, ইউআই onClick
মতো ইভেন্টগুলি উত্থাপন করে। এই ইভেন্টগুলি অ্যাপ্লিকেশন যুক্তিটিকে অবহিত করা উচিত, যা পরে অ্যাপটির অবস্থা পরিবর্তন করতে পারে। যখন রাষ্ট্রটি পরিবর্তিত হয়, তখন নতুন ডেটা সহ কমপোজেবল ফাংশনগুলি আবার কল করা হয়। এর ফলে ইউআই উপাদানগুলি পুনর্নির্মাণের কারণ হয়-এই প্রক্রিয়াটিকে পুনরুদ্ধার বলা হয়।
চিত্র 3। ব্যবহারকারী একটি ইউআই উপাদানটির সাথে ইন্টারঅ্যাক্ট করেছেন, যার ফলে ইভেন্টটি ট্রিগার হয়ে যায়। অ্যাপ লজিক ইভেন্টটিতে সাড়া দেয়, তারপরে কমপোজেবল ফাংশনগুলি স্বয়ংক্রিয়ভাবে নতুন পরামিতিগুলির সাথে আবার কল করা হয়, প্রয়োজনে।
গতিশীল বিষয়বস্তু
যেহেতু কমপোজেবল ফাংশনগুলি এক্সএমএল এর পরিবর্তে কোটলিনে লেখা হয়, সেগুলি অন্য কোনও কোটলিন কোডের মতো গতিশীল হতে পারে। উদাহরণস্বরূপ, ধরুন আপনি এমন একটি ইউআই তৈরি করতে চান যা ব্যবহারকারীদের একটি তালিকাকে শুভেচ্ছা জানায়:
@Composable fun Greeting(names: List<String>) { for (name in names) { Text("Hello $name") } }
এই ফাংশনটি নামগুলির একটি তালিকায় নেয় এবং প্রতিটি ব্যবহারকারীর জন্য একটি শুভেচ্ছা উত্পন্ন করে। কমপোজেবল ফাংশনগুলি বেশ পরিশীলিত হতে পারে। আপনি যদি কোনও নির্দিষ্ট ইউআই উপাদান দেখাতে চান কিনা তা সিদ্ধান্ত নিতে আপনি if
বিবৃতিগুলি ব্যবহার করতে পারেন। আপনি লুপ ব্যবহার করতে পারেন। আপনি সহায়ক ফাংশন কল করতে পারেন। আপনার অন্তর্নিহিত ভাষার সম্পূর্ণ নমনীয়তা রয়েছে। এই শক্তি এবং নমনীয়তা জেটপ্যাক রচনার অন্যতম মূল সুবিধা।
পুনর্গঠন
একটি অপরিহার্য ইউআই মডেলটিতে, একটি উইজেট পরিবর্তন করতে, আপনি উইজেটে একটি সেটারকে তার অভ্যন্তরীণ অবস্থার পরিবর্তন করতে কল করেন। রচনাটিতে, আপনি নতুন ডেটা সহ আবার কমপোজেবল ফাংশনটিকে কল করুন। এটি করার ফলে ফাংশনটি পুনরুদ্ধার করা হয় -ফাংশন দ্বারা নির্গত উইজেটগুলি নতুন ডেটা সহ প্রয়োজনে পুনরায় সাজানো হয়। কম্পোজ ফ্রেমওয়ার্ক বুদ্ধিমত্তার সাথে শুধুমাত্র পরিবর্তিত উপাদানগুলিকে পুনরায় কম্পোজ করতে পারে।
উদাহরণস্বরূপ, এই কমপোজেবল ফাংশনটি বিবেচনা করুন যা একটি বোতাম প্রদর্শন করে:
@Composable fun ClickCounter(clicks: Int, onClick: () -> Unit) { Button(onClick = onClick) { Text("I've been clicked $clicks times") } }
প্রতিবার বোতামটি ক্লিক করা হলে, কলার clicks
মান আপডেট করে। রচনাটি নতুন মানটি দেখানোর জন্য আবার Text
ফাংশন সহ ল্যাম্বডাকে কল করে; এই প্রক্রিয়াটিকে পুনরুদ্ধার বলা হয়। অন্যান্য ফাংশনগুলি যা মানের উপর নির্ভর করে না তা পুনরুদ্ধার করা হয় না।
যেমনটি আমরা আলোচনা করেছি, পুরো ইউআই গাছটি পুনরায় সংমিশ্রণ করা গণনামূলকভাবে ব্যয়বহুল হতে পারে, যা কম্পিউটিং শক্তি এবং ব্যাটারির জীবন ব্যবহার করে। রচনাটি এই বুদ্ধিমান পুনরুদ্ধারটি দিয়ে এই সমস্যাটি সমাধান করে।
ইনপুটগুলি পরিবর্তিত হওয়ার সাথে সাথে আপনার কমপোজেবল ফাংশনগুলিকে আবার কল করার প্রক্রিয়া হ'ল পুনরুদ্ধার। এটি ঘটে যখন ফাংশনের ইনপুট পরিবর্তন হয়। যখন কম্পোজ নতুন ইনপুটগুলির উপর ভিত্তি করে পুনর্গঠন করা হয়, তখন এটি শুধুমাত্র সেই ফাংশন বা ল্যাম্বডাসগুলিকে কল করে যা পরিবর্তিত হতে পারে এবং বাকিগুলি এড়িয়ে যায়। পরিবর্তিত প্যারামিটার নেই এমন সমস্ত ফাংশন বা ল্যাম্বডাস বাদ দিয়ে, রচনা দক্ষতার সাথে পুনরায় রচনা করতে পারে।
কমপোজেবল ফাংশনগুলি সম্পাদন করা থেকে পার্শ্ব প্রতিক্রিয়াগুলির উপর কখনই নির্ভর করবেন না, যেহেতু কোনও ফাংশনের পুনঃনির্মাণ এড়ানো যেতে পারে। আপনি যদি তা করেন তবে ব্যবহারকারীরা আপনার অ্যাপ্লিকেশনটিতে অদ্ভুত এবং অপ্রত্যাশিত আচরণ অনুভব করতে পারেন। একটি পার্শ্ব-প্রতিক্রিয়া হ'ল এমন কোনও পরিবর্তন যা আপনার অ্যাপ্লিকেশনটির বাকী অংশে দৃশ্যমান। উদাহরণস্বরূপ, এই ক্রিয়াগুলি সমস্ত বিপজ্জনক পার্শ্ব প্রতিক্রিয়া:
- একটি ভাগ করা বস্তুর সম্পত্তি লিখুন
-
ViewModel
একটি পর্যবেক্ষণযোগ্য আপডেট করা - ভাগ করা পছন্দগুলি আপডেট করা
কমপোজেবল ফাংশনগুলি প্রতিটি ফ্রেমের মতো প্রায়শই পুনরায় কার্যকর করা যেতে পারে যেমন কোনও অ্যানিমেশন যখন রেন্ডার করা হয়। অ্যানিমেশনগুলির সময় জ্যাঙ্ক এড়াতে কমপোজেবল ফাংশনগুলি দ্রুত হওয়া উচিত। আপনার যদি ব্যয়বহুল অপারেশনগুলি যেমন ভাগ করা পছন্দগুলি থেকে পড়া প্রয়োজন হয় তবে এটি একটি ব্যাকগ্রাউন্ড করুটাইন এ করুন এবং মান ফলাফলটি একটি প্যারামিটার হিসাবে কমপোজেবল ফাংশনে পাস করুন।
উদাহরণ হিসাবে, এই কোডটি SharedPreferences
ক্ষেত্রে একটি মান আপডেট করার জন্য একটি কমপোজেবল তৈরি করে। কমপোজেবলটি ভাগ করে নেওয়া পছন্দগুলি থেকে নিজেই পড়তে বা লিখতে হবে না। পরিবর্তে, এই কোডটি পঠনকে সরিয়ে দেয় এবং একটি ব্যাকগ্রাউন্ড করুটিনে একটি ViewModel
লিখুন। অ্যাপ্লিকেশন লজিক একটি আপডেট ট্রিগার করতে কলব্যাকের সাথে বর্তমান মানটি পাস করে।
@Composable fun SharedPrefsToggle( text: String, value: Boolean, onValueChanged: (Boolean) -> Unit ) { Row { Text(text) Checkbox(checked = value, onCheckedChange = onValueChanged) } }
এই দস্তাবেজটি আপনি যখন রচনাটি ব্যবহার করেন তখন সচেতন হওয়ার জন্য বেশ কয়েকটি বিষয় নিয়ে আলোচনা করে:
- পুনরুদ্ধার যতটা সম্ভব কমপোজেবল ফাংশন এবং ল্যাম্বডাসকে এড়িয়ে যায়।
- পুনরুদ্ধার আশাবাদী এবং বাতিল হতে পারে।
- একটি কমপোজেবল ফাংশনটি প্রায়শই প্রায়শই চালিত হতে পারে, প্রায়শই অ্যানিমেশনের প্রতিটি ফ্রেম হিসাবে।
- কমপোজেবল ফাংশনগুলি সমান্তরালে কার্যকর করতে পারে।
- কমপোজেবল ফাংশনগুলি যে কোনও ক্রমে কার্যকর করতে পারে।
নিম্নলিখিত বিভাগগুলি পুনরুদ্ধারকে সমর্থন করার জন্য কীভাবে কমপোজেবল ফাংশনগুলি তৈরি করবেন তা কভার করবে। প্রতিটি ক্ষেত্রে, সর্বোত্তম অনুশীলন হ'ল আপনার কম্পোজেবল ফাংশনগুলি দ্রুত, আদর্শ এবং পার্শ্ব-প্রতিক্রিয়া মুক্ত রাখা।
পুনরুদ্ধার যতটা সম্ভব এড়িয়ে যায়
যখন আপনার ইউআইয়ের অংশগুলি অবৈধ থাকে, তখন রচনাটি আপডেট করা দরকার এমন অংশগুলি পুনরায় সংযুক্ত করার জন্য রচনাটি যথাসাধ্য চেষ্টা করে। এর অর্থ এটি ইউআই গাছের উপরে বা নীচে কোনও কম্পোজেবলকে কার্যকর না করে একটি একক বোতামের কম্পোজেবল পুনরায় চালাতে এড়িয়ে যেতে পারে।
প্রতিটি কমপোজেবল ফাংশন এবং ল্যাম্বডা নিজেই পুনরায় সংযুক্ত হতে পারে। এখানে একটি উদাহরণ রয়েছে যা প্রদর্শন করে যে কোনও তালিকা রেন্ডার করার সময় কীভাবে পুনরুদ্ধারগুলি কিছু উপাদান এড়িয়ে যেতে পারে:
/** * Display a list of names the user can click with a header */ @Composable fun NamePicker( header: String, names: List<String>, onNameClicked: (String) -> Unit ) { Column { // this will recompose when [header] changes, but not when [names] changes Text(header, style = MaterialTheme.typography.bodyLarge) HorizontalDivider() // LazyColumn is the Compose version of a RecyclerView. // The lambda passed to items() is similar to a RecyclerView.ViewHolder. LazyColumn { items(names) { name -> // When an item's [name] updates, the adapter for that item // will recompose. This will not recompose when [header] changes NamePickerItem(name, onNameClicked) } } } } /** * Display a single name the user can click. */ @Composable private fun NamePickerItem(name: String, onClicked: (String) -> Unit) { Text(name, Modifier.clickable(onClick = { onClicked(name) })) }
এই স্কোপগুলির প্রত্যেকটিই কোনও পুনঃনির্মাণের সময় কার্যকর করা একমাত্র জিনিস হতে পারে। header
পরিবর্তিত হলে তার পিতামাতার কোনওটি কার্যকর না করেই কমপোজ ল্যাম্বডা Column
এড়িয়ে যেতে পারে। এবং Column
সম্পাদন করার সময়, কমপোজ names
পরিবর্তন না করলে LazyColumn
এর আইটেমগুলি এড়িয়ে যেতে বেছে নিতে পারে।
আবার, সমস্ত কমপোজেবল ফাংশন বা ল্যাম্বডাস সম্পাদন করা পার্শ্ব-প্রতিক্রিয়া মুক্ত হওয়া উচিত। যখন আপনার কোনও পার্শ্ব-প্রতিক্রিয়া সম্পাদন করতে হবে, তখন এটি একটি কলব্যাক থেকে ট্রিগার করুন।
পুনরুদ্ধার আশাবাদী
যখনই রচনাটি মনে হয় তখন পুনরুদ্ধার শুরু হয় যে কোনও কমপোজেবলের পরামিতিগুলি পরিবর্তিত হতে পারে। পুনঃনির্মাণটি আশাবাদী, যার অর্থ রচনাগুলি আবার প্যারামিটারগুলি পরিবর্তনের আগে পুনরুদ্ধার শেষ করার প্রত্যাশা করে। যদি কোনও প্যারামিটার পুনরুদ্ধার শেষ হওয়ার আগে পরিবর্তিত হয় তবে রচনাটি পুনরুদ্ধারটি বাতিল করতে পারে এবং নতুন প্যারামিটার দিয়ে এটি পুনরায় চালু করতে পারে।
যখন পুনরুদ্ধার বাতিল করা হয়, তখন UI গাছটিকে পুনরুদ্ধার থেকে ছাড়িয়ে রচনা করুন। আপনার যদি কোনও পার্শ্ব-প্রতিক্রিয়া থাকে যা ইউআই প্রদর্শিত হচ্ছে তার উপর নির্ভর করে, রচনা বাতিল করা হলেও পার্শ্ব-প্রতিক্রিয়া প্রয়োগ করা হবে। এটি বেমানান অ্যাপ্লিকেশন অবস্থার দিকে নিয়ে যেতে পারে।
নিশ্চিত করুন যে সমস্ত কমপোজেবল ফাংশন এবং ল্যাম্বডাস আইডেম্পোটেন্ট এবং আশাবাদী পুনরুদ্ধার পরিচালনা করতে পার্শ্ব-প্রতিক্রিয়া মুক্ত।
কমপোজেবল ফাংশনগুলি বেশ ঘন ঘন চলতে পারে
কিছু ক্ষেত্রে, একটি UI অ্যানিমেশনের প্রতিটি ফ্রেমের জন্য একটি কমপোজেবল ফাংশন চলতে পারে। যদি ফাংশনটি ডিভাইস স্টোরেজ থেকে পড়ার মতো ব্যয়বহুল ক্রিয়াকলাপ সম্পাদন করে তবে ফাংশনটি ইউআই জ্যাঙ্কের কারণ হতে পারে।
উদাহরণস্বরূপ, যদি আপনার উইজেটটি ডিভাইস সেটিংস পড়ার চেষ্টা করে, তবে এটি আপনার অ্যাপের পারফরম্যান্সে বিপর্যয়কর প্রভাব সহ এই সেটিংসকে কয়েকশ বার কয়েকবার পড়তে পারে।
যদি আপনার কমপোজেবল ফাংশনটির ডেটা প্রয়োজন হয় তবে এটি ডেটার জন্য পরামিতিগুলি সংজ্ঞায়িত করা উচিত। তারপরে আপনি রচনার বাইরে ব্যয়বহুল কাজটি অন্য থ্রেডে স্থানান্তর করতে পারেন এবং mutableStateOf
বা LiveData
ব্যবহার করে রচনা করতে ডেটা পাস করতে পারেন।
কমপোজেবল ফাংশনগুলি সমান্তরালভাবে চালানো যেতে পারে
সমান্তরালভাবে কমপোজেবল ফাংশনগুলি চালিয়ে রচনাটি পুনরুদ্ধারকে অনুকূল করতে পারে। এটি রচনাটি একাধিক কোরের সুবিধা নিতে দেয় এবং কম অগ্রাধিকারে স্ক্রিনে নয় এমন কমপোজেবল ফাংশনগুলি চালায়।
এই অপ্টিমাইজেশনের অর্থ একটি কমপোজেবল ফাংশন ব্যাকগ্রাউন্ড থ্রেডগুলির একটি পুলের মধ্যে কার্যকর করতে পারে। যদি কোনও কমপোজেবল ফাংশন কোনও ViewModel
কোনও ফাংশনকে কল করে তবে রচনাটি একই সাথে বেশ কয়েকটি থ্রেড থেকে সেই ফাংশনটিকে কল করতে পারে।
আপনার অ্যাপ্লিকেশনটি সঠিকভাবে আচরণ করে তা নিশ্চিত করার জন্য, সমস্ত কমপোজেবল ফাংশনগুলির কোনও পার্শ্ব-প্রতিক্রিয়া থাকা উচিত নয়। পরিবর্তে, কলব্যাক যেমন onClick
থেকে সাইড-এফেক্টগুলি ট্রিগার করে যা সর্বদা ইউআই থ্রেডে কার্যকর করে।
যখন কোনও কমপোজেবল ফাংশনটি অনুরোধ করা হয়, তখন কলার থেকে আলাদা থ্রেডে অনুরোধটি ঘটতে পারে। এর অর্থ কোড যা একটি কম্পোজেবল ল্যাম্বডায় ভেরিয়েবলগুলি পরিবর্তন করে এড়ানো উচিত-উভয়ই কারণ এই জাতীয় কোডটি থ্রেড-নিরাপদ নয়, এবং কারণ এটি কম্পোজেবল ল্যাম্বডার একটি অনিবার্য পার্শ্ব-প্রতিক্রিয়া।
এখানে একটি উদাহরণ দেখানো একটি উদাহরণ যা একটি তালিকা এবং এর গণনা প্রদর্শন করে:
@Composable fun ListComposable(myList: List<String>) { Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Text("Item: $item") } } Text("Count: ${myList.size}") } }
এই কোডটি পার্শ্ব-প্রতিক্রিয়া মুক্ত এবং ইনপুট তালিকাটি ইউআইতে রূপান্তর করে। এটি একটি ছোট তালিকা প্রদর্শনের জন্য দুর্দান্ত কোড। তবে, যদি ফাংশনটি কোনও স্থানীয় ভেরিয়েবলের কাছে লিখে তবে এই কোডটি থ্রেড-নিরাপদ বা সঠিক হবে না:
@Composable fun ListWithBug(myList: List<String>) { var items = 0 Row(horizontalArrangement = Arrangement.SpaceBetween) { Column { for (item in myList) { Card { Text("Item: $item") items++ // Avoid! Side-effect of the column recomposing. } } } Text("Count: $items") } }
এই উদাহরণে, items
প্রতিটি পুনঃনির্মাণের সাথে সংশোধন করা হয়। এটি কোনও অ্যানিমেশনের প্রতিটি ফ্রেম হতে পারে, বা তালিকাটি আপডেট হয়। যেভাবেই হোক, ইউআই ভুল গণনা প্রদর্শন করবে। এ কারণে, লেখার মতো লেখার পক্ষে এটি কমপোজে সমর্থিত নয়; এই লেখাগুলি নিষিদ্ধ করে, আমরা ফ্রেমওয়ার্কটিকে থ্রেডগুলি কমপোজেবল ল্যাম্বডাস কার্যকর করতে পরিবর্তন করার অনুমতি দিই।
কমপোজেবল ফাংশনগুলি যে কোনও ক্রমে কার্যকর করতে পারে
আপনি যদি কোনও কমপোজেবল ফাংশনের জন্য কোডটি দেখেন তবে আপনি ধরে নিতে পারেন যে কোডটি প্রদর্শিত হয় সেই ক্রমে চালিত হয়। তবে এটি সত্য হওয়ার গ্যারান্টিযুক্ত নয়। যদি কোনও কমপোজেবল ফাংশনে অন্যান্য কমপোজেবল ফাংশনগুলিতে কল থাকে তবে সেই ফাংশনগুলি যে কোনও ক্রমে চলতে পারে। কিছু ইউআই উপাদান অন্যের চেয়ে বেশি অগ্রাধিকার এবং এগুলি প্রথমে আঁকতে স্বীকৃতি দেওয়ার বিকল্পটি কমপোজে রয়েছে।
উদাহরণস্বরূপ, ধরুন আপনার কাছে একটি ট্যাব লেআউটে তিনটি স্ক্রিন আঁকতে এর মতো কোড রয়েছে:
@Composable fun ButtonRow() { MyFancyNavigation { StartScreen() MiddleScreen() EndScreen() } }
StartScreen
, MiddleScreen
এবং EndScreen
কলগুলি কোনও ক্রমে ঘটতে পারে। এর অর্থ আপনি উদাহরণস্বরূপ, StartScreen()
কিছু গ্লোবাল ভেরিয়েবল (একটি পার্শ্ব-প্রতিক্রিয়া) সেট করতে পারবেন না এবং MiddleScreen()
সেই পরিবর্তনের সুবিধা নিতে পারবেন না। পরিবর্তে, এই ফাংশনগুলির প্রত্যেকটির স্ব-অন্তর্ভুক্ত হওয়া দরকার।
আরও জানুন
রচনা এবং কম্পোজেবল ফাংশনগুলিতে কীভাবে ভাবতে হয় সে সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন।
ভিডিও
{% শব্দার্থে %}আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- জেটপ্যাক রচনার জন্য কোটলিন
- রাজ্য এবং জেটপ্যাক রচনা
- জেটপ্যাক রচনা আর্কিটেকচারাল লেয়ারিং