ভিউ বাইন্ডিং Android Jetpack-এর অংশ।
ভিউ বাইন্ডিং হল এমন একটি ফিচার যা ভিউয়ের সাথে ইন্টার্যাক্ট করে এমন কোড লেখার কাজকে সহজ করে তোলে। কোনও মডিউলে ভিউ বাইন্ডিং চালু করা হলে, এটি সেই মডিউলে উপস্থিত প্রতিটি XML লেআউট ফাইলের জন্য একটি বাইন্ডিং ক্লাস তৈরি করে। বাইন্ডিং ক্লাসের একটি ইনস্ট্যান্সে সংশ্লিষ্ট লেআউটে আইডি আছে এমন সব ভিউয়ের সরাসরি রেফারেন্স থাকে।
বেশিরভাগ ক্ষেত্রে, ভিউ বাইন্ডিং findViewById-কে রিপ্লেস করে।
সেটআপ
মডিউল-বাই-মডিউল ভিত্তিতে ভিউ বাইন্ডিং চালু করা হয়। কোনও মডিউলে ভিউ বাইন্ডিং চালু করতে, মডিউল-লেভেল build.gradle ফাইলে viewBinding বিল্ড বিকল্পটি true-এ সেট করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
গ্ৰুভি
android { ... buildFeatures { viewBinding true } }
Kotlin
android { ... buildFeatures { viewBinding = true } }
বাইন্ডিং ক্লাস তৈরি করার সময় আপনি যদি কোনও লেআউট ফাইলকে উপেক্ষা করতে চান, তাহলে সেই লেআউট ফাইলের রুট ভিউতে
tools:viewBindingIgnore="true" অ্যাট্রিবিউট যোগ করুন:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
ব্যবহার
কোনও মডিউলের জন্য ভিউ বাইন্ডিং চালু করা থাকলে, মডিউলে থাকা প্রতিটি XML লেআউট ফাইলের জন্য একটি বাইন্ডিং ক্লাস তৈরি করা হয়। প্রতিটি বাইন্ডিং ক্লাসে রুট ভিউ এবং আইডি আছে এমন সব ভিউয়ের রেফারেন্স থাকে। XML ফাইলের নাম Pascal case-এ পরিবর্তন করে এবং শেষে "Binding" শব্দটি যোগ করে বাইন্ডিং ক্লাসের নাম তৈরি করা হয়।
যেমন, result_profile.xml নামের একটি লেআউট ফাইলের কথা ভাবুন, যাতে
নিম্নলিখিত তথ্য আছে:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
জেনারেট করা বাইন্ডিং ক্লাসকে ResultProfileBinding বলা হয়। এই ক্লাসে দুটি
ফিল্ড আছে: name নামের একটি TextView এবং button নামের একটি Button। লেআউটে
ImageView-এর কোনও আইডি নেই, তাই বাইন্ডিং ক্লাসে
এর কোনও রেফারেন্স নেই।
প্রতিটি বাইন্ডিং ক্লাসে একটি getRoot() পদ্ধতিও অন্তর্ভুক্ত থাকে, যা সংশ্লিষ্ট লেআউট ফাইলের রুট ভিউয়ের জন্য একটি সরাসরি রেফারেন্স প্রদান করে। এই উদাহরণে,
ResultProfileBinding ক্লাসের getRoot() পদ্ধতি
LinearLayout রুট ভিউ ফিরিয়ে দেয়।
নিম্নলিখিত বিভাগগুলি অ্যাক্টিভিটি এবং ফ্র্যাগমেন্টে জেনারেট করা বাইন্ডিং ক্লাসের ব্যবহার দেখায়।
অ্যাক্টিভিটিতে ভিউ বাইন্ডিং ব্যবহার করুন
কোনও অ্যাক্টিভিটির সাথে ব্যবহার করার জন্য বাইন্ডিং ক্লাসের ইনস্ট্যান্স সেট-আপ করতে, অ্যাক্টিভিটির
onCreate() পদ্ধতিতে
নিম্নলিখিত ধাপগুলি অনুসরণ করুন:
- জেনারেট করা বাইন্ডিং ক্লাসে অন্তর্ভুক্ত স্ট্যাটিক
inflate()মেথড কল করুন। এটি অ্যাক্টিভিটি ব্যবহার করার জন্য বাইন্ডিং ক্লাসের একটি ইনস্ট্যান্স তৈরি করে। getRoot()মেথড কল করে অথবা Kotlin প্রপার্টি সিনট্যাক্স ব্যবহার করে রুট ভিউয়ের রেফারেন্স পান।- স্ক্রিনে অ্যাক্টিভ ভিউ হিসেবে সেট করতে, রুট ভিউ
setContentView()-এ পাস করুন।
এইসব ধাপ নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
Kotlin
private lateinit var binding: ResultProfileBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }
জাভা
private ResultProfileBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ResultProfileBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); }
আপনি এখন যেকোনও ভিউ রেফারেন্স করতে বাইন্ডিং ক্লাসের ইনস্ট্যান্স ব্যবহার করতে পারবেন:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
জাভা
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
ফ্র্যাগমেন্টে ভিউ বাইন্ডিং ব্যবহার করা
ফ্র্যাগমেন্টের সাথে ব্যবহার করার জন্য বাইন্ডিং ক্লাসের ইনস্ট্যান্স সেট-আপ করতে, ফ্র্যাগমেন্টের
onCreateView()
মেথডে নিম্নলিখিত ধাপগুলি
সম্পূর্ণ করুন:
- জেনারেট করা বাইন্ডিং ক্লাসে অন্তর্ভুক্ত স্ট্যাটিক
inflate()মেথড কল করুন। এটি ফ্র্যাগমেন্টের ব্যবহারের জন্য বাইন্ডিং ক্লাসের একটি ইনস্ট্যান্স তৈরি করে। getRoot()মেথড কল করে অথবা Kotlin প্রপার্টি সিনট্যাক্স ব্যবহার করে রুট ভিউয়ের রেফারেন্স পান।onCreateView()পদ্ধতি থেকে রুট ভিউ ফিরিয়ে দিন যাতে এটি স্ক্রিনে অ্যাক্টিভ ভিউ হিসেবে সেট করা যায়।
Kotlin
private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view } override fun onDestroyView() { super.onDestroyView() _binding = null }
জাভা
private ResultProfileBinding binding; @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = ResultProfileBinding.inflate(inflater, container, false); View view = binding.getRoot(); return view; } @Override public void onDestroyView() { super.onDestroyView(); binding = null; }
আপনি এখন যেকোনও ভিউ রেফারেন্স করতে বাইন্ডিং ক্লাসের ইনস্ট্যান্স ব্যবহার করতে পারবেন:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
জাভা
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
বিভিন্ন কনফিগারেশনের জন্য ইঙ্গিত প্রদান করুন
আপনি যখন একাধিক কনফিগারেশন জুড়ে ভিউ ঘোষণা করেন, তখন মাঝে মাঝে নির্দিষ্ট লেআউটের উপর নির্ভর করে একটি ভিন্ন ভিউ টাইপ ব্যবহার করা যুক্তিযুক্ত। নিচের কোড স্নিপেট এর একটি উদাহরণ দেখায়:
# in res/layout/example.xml
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" />
এই ক্ষেত্রে, আপনি আশা করতে পারেন যে জেনারেট করা ক্লাস TextView ধরনের একটি ফিল্ড userBio
প্রকাশ করবে, কারণ TextView হল সাধারণ মূল ক্লাস। প্রযুক্তিগত সীমাবদ্ধতার কারণে, ভিউ বাইন্ডিং কোড জেনারেটর এটি নির্ধারণ করতে পারে না এবং
পরিবর্তে একটি View ফিল্ড তৈরি করে। এর জন্য পরে binding.userBio as TextView-এর সাথে ফিল্ড কাস্ট করতে হবে।
এই সীমাবদ্ধতা এড়াতে, ভিউ বাইন্ডিং tools:viewBindingType
অ্যাট্রিবিউটকে সাপোর্ট করে, যা আপনাকে কম্পাইলারকে জানাতে দেয় যে জেনারেট করা কোডে কোন ধরন ব্যবহার করতে হবে।
আগের উদাহরণে, কম্পাইলারকে দিয়ে TextView হিসেবে ফিল্ড তৈরি করার জন্য আপনি এই অ্যাট্রিবিউট ব্যবহার করতে পারেন:
# in res/layout/example.xml (unchanged)
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />
অন্য একটি উদাহরণে, ধরুন আপনার দুটি লেআউট আছে, একটিতে BottomNavigationView এবং অন্যটিতে NavigationRailView আছে। উভয়
ক্লাস NavigationBarView এক্সটেন্ড করে, যার মধ্যে বেশিরভাগ ইমপ্লিমেন্টেশন
বিবরণ থাকে। বর্তমান লেআউটে ঠিক কোন সাবক্লাস আছে তা যদি আপনার কোডের জানার প্রয়োজন না হয়, তাহলে আপনি tools:viewBindingType ব্যবহার করে দুটি লেআউটেই জেনারেট করা টাইপ
NavigationBarView-এ সেট করতে পারেন:
# in res/layout/navigation_example.xml
<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
# in res/layout-w720/navigation_example.xml
<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
কোড জেনারেট করার সময় ভিউ বাইন্ডিং এই অ্যাট্রিবিউটের ভ্যালু যাচাই করতে পারে না। কম্পাইল-টাইম ও রানটাইম সমস্যা এড়াতে, ভ্যালুকে নিম্নলিখিত শর্ত পূরণ করতে হবে:
- ভ্যালুটি অবশ্যই এমন একটি ক্লাস হতে হবে যা
android.view.Viewথেকে ইনহেরিট করে। ভ্যালুটি অবশ্যই যে ট্যাগে রাখা হয়েছে তার সুপারক্লাস হতে হবে। যেমন, নিম্নলিখিত ভ্যালু কাজ করে না:
<TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. --> <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->চূড়ান্ত ধরনটি সব কনফিগারেশন জুড়ে ধারাবাহিকভাবে সমাধান করতে হবে।
findViewById থেকে পার্থক্য
findViewById ব্যবহার করার তুলনায় ভিউ বাইন্ডিংয়ের গুরুত্বপূর্ণ সুবিধা আছে:
- Null সেফটি: যেহেতু ভিউ বাইন্ডিং ভিউয়ের সরাসরি রেফারেন্স তৈরি করে,
তাই ভুল ভিউ আইডির কারণে Null পয়েন্টার এক্সেপশনের কোনও ঝুঁকি থাকে না।
এছাড়াও, কোনও ভিউ লেআউটের শুধুমাত্র কিছু কনফিগারেশনে উপস্থিত থাকলে, বাইন্ডিং ক্লাসে এটির রেফারেন্স সহ ফিল্ডটি
@Nullableদিয়ে চিহ্নিত করা হয়। - টাইপ নিরাপত্তা: প্রতিটি বাইন্ডিং ক্লাসের ফিল্ডে এমন ধরন থাকে যা XML ফাইলে রেফার করা ভিউয়ের সাথে ম্যাচ করে। এর অর্থ হল, ক্লাস কাস্ট এক্সেপশনের কোনও ঝুঁকি নেই।
এই পার্থক্যের অর্থ হল আপনার লেআউট এবং কোডের মধ্যে অসঙ্গতি যার ফলে আপনার বিল্ড রানটাইমের পরিবর্তে কম্পাইল টাইমে ব্যর্থ হয়।
ডেটা বাইন্ডিংয়ের সাথে তুলনা
ভিউ বাইন্ডিং ও ডেটা বাইন্ডিং, দুটিই বাইন্ডিং ক্লাস তৈরি করে যা আপনি সরাসরি ভিউ রেফারেন্স করতে ব্যবহার করতে পারবেন। তবে, ভিউ বাইন্ডিংয়ের উদ্দেশ্য হল আরও সহজ ব্যবহারের কেস ম্যানেজ করা এবং ডেটা বাইন্ডিংয়ের তুলনায় নিম্নলিখিত সুবিধা প্রদান করা:
- আরও দ্রুত কম্পাইলেশন: ভিউ বাইন্ডিংয়ের জন্য কোনও অ্যানোটেশন প্রসেসিংয়ের প্রয়োজন হয় না, তাই কম্পাইল করার সময় আরও দ্রুত হয়।
- ব্যবহার করা সহজ: ভিউ বাইন্ডিংয়ের জন্য বিশেষভাবে ট্যাগ করা XML লেআউট ফাইলের প্রয়োজন হয় না, তাই এটি আপনার অ্যাপে দ্রুত গ্রহণ করা যায়। আপনি কোনও মডিউলে ভিউ বাইন্ডিং চালু করলে, এটি অটোমেটিক সেই মডিউলের সব লেআউটে প্রযোজ্য হয়।
অন্যদিকে, ডেটা বাইন্ডিংয়ের তুলনায় ভিউ বাইন্ডিংয়ের নিম্নলিখিত সীমাবদ্ধতা আছে:
- ভিউ বাইন্ডিং লেআউট ভেরিয়েবল বা লেআউট এক্সপ্রেশন সাপোর্ট করে না, তাই XML লেআউট ফাইল থেকে সরাসরি ডায়নামিক UI কন্টেন্ট ঘোষণা করার জন্য এটি ব্যবহার করা যায় না।
- ভিউ বাইন্ডিংয়ে টু-ওয়ে ডেটা বাইন্ডিং কাজ করে না।
এইসব বিষয় বিবেচনা করে, কিছু ক্ষেত্রে কোনও প্রোজেক্টে ভিউ বাইন্ডিং ও ডেটা বাইন্ডিং, দুটিই ব্যবহার করা সবচেয়ে ভালো। আপনি এমন লেআউটে ডেটা বাইন্ডিং ব্যবহার করতে পারেন যার জন্য উন্নত ফিচার প্রয়োজন এবং এমন লেআউটে ভিউ বাইন্ডিং ব্যবহার করতে পারেন যার জন্য উন্নত ফিচার প্রয়োজন নেই।
অতিরিক্ত রিসোর্স
ভিউ বাইন্ডিং সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন:
ব্লগ
ভিডিও
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- Kotlin সিন্থেটিক্স থেকে Jetpack ভিউ বাইন্ডিংয়ে মাইগ্রেট করা
- লেআউট ও বাইন্ডিং এক্সপ্রেশন
- অ্যাপ আর্কিটেকচার: UI লেয়ার - শুরু করা - Android ডেভেলপার