এক্সপ্রেশন ল্যাঙ্গুয়েজ আপনাকে এমন এক্সপ্রেশন লিখতে দেয় যা ভিউয়ের মাধ্যমে ডিসপ্যাচ করা ইভেন্ট ম্যানেজ করে। আপনার ডেটা অবজেক্টের সাথে লেআউটে ভিউ বাইন্ড করার জন্য প্রয়োজনীয় ক্লাস ডেটা বাইন্ডিং লাইব্রেরি অটোমেটিক তৈরি করে।
ডেটা বাইন্ডিং লেআউট ফাইলগুলি কিছুটা আলাদা এবং
layout-এর রুট ট্যাগ দিয়ে শুরু হয়, তারপরে একটি data এলিমেন্ট এবং একটি view রুট এলিমেন্ট থাকে। এই ভিউ
এলিমেন্ট হল নন-বাইন্ডিং লেআউট ফাইলে আপনার রুট। নিম্নলিখিত কোডটি
একটি স্যাম্পেল লে-আউট ফাইল দেখায়:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
data-এর মধ্যে user ভেরিয়েবল এমন একটি প্রপার্টি বর্ণনা করে যা এই লেআউটের মধ্যে ব্যবহার করা যেতে পারে:
<variable name="user" type="com.example.User" />
লেআউটের মধ্যে এক্সপ্রেশনগুলি @{} সিনট্যাক্স ব্যবহার করে অ্যাট্রিবিউট প্রপার্টিতে লেখা হয়। নিচের উদাহরণে, TextView টেক্সটটি user ভেরিয়েবলের
firstName প্রপার্টিতে সেট করা হয়েছে:
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}" />
ডেটা অবজেক্ট
ধরুন, User এন্টিটি বর্ণনা করার জন্য আপনার কাছে একটি প্লেন অবজেক্ট আছে:
Kotlin
data class User(val firstName: String, val lastName: String)
জাভা
public class User { public final String firstName; public final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }
এই ধরনের অবজেক্টে এমন ডেটা থাকে যা কখনও পরিবর্তন হয় না। অ্যাপে এমন ডেটা থাকা সাধারণ ব্যাপার যা একবার পড়া হয় এবং তারপরে আর কখনও পরিবর্তন হয় না। এছাড়াও, এমন অবজেক্ট ব্যবহার করা সম্ভব যা কনভেনশনের সেট অনুসরণ করে, যেমন Java প্রোগ্রামিং ল্যাঙ্গুয়েজে অ্যাক্সেসর পদ্ধতি ব্যবহার করা, যা নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
Kotlin
// Not applicable in Kotlin. data class User(val firstName: String, val lastName: String)
জাভা
public class User { private final String firstName; private final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; } }
ডেটা বাইন্ডিংয়ের দৃষ্টিকোণ থেকে, এই দুটি ক্লাস সমতুল্য। android:text
অ্যাট্রিবিউটের জন্য ব্যবহৃত
@{user.firstName} এক্সপ্রেশনটি প্রথম ক্লাসের firstName ফিল্ড এবং
পরবর্তী ক্লাসের getFirstName() পদ্ধতি অ্যাক্সেস করে। এছাড়াও, এটি
firstName()-এ সমাধান করা হয়েছে, যদি সেই পদ্ধতিটি থাকে।
ডেটা বাইন্ডিং
প্রতিটি লেআউট ফাইলের জন্য একটি বাইন্ডিং ক্লাস তৈরি করা হয়। ডিফল্ট হিসেবে,
ক্লাসের নাম লেআউট ফাইলের নামের উপর ভিত্তি করে হয়, যা প্যাসকেল কেসে কনভার্ট করা হয় এবং
এতে Binding সাফিক্স যোগ করা হয়। যেমন, আগের লেআউট ফাইলের নাম হল
activity_main.xml, তাই সংশ্লিষ্ট জেনারেট করা বাইন্ডিং ক্লাস হল
ActivityMainBinding।
এই ক্লাস লে-আউট প্রপার্টি থেকে সব বাইন্ডিং হোল্ড করে—যেমন,
user ভেরিয়েবল—লে-আউটের ভিউতে এবং বাইন্ডিং এক্সপ্রেশনের জন্য
কীভাবে ভ্যালু অ্যাসাইন করতে হয় তা জানে। আমরা সাজেস্ট করি যে লেআউট ইনফ্লেট করার সময় বাইন্ডিং তৈরি করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: ActivityMainBinding = DataBindingUtil.setContentView( this, R.layout.activity_main) binding.user = User("Test", "User") }
জাভা
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); User user = new User("Test", "User"); binding.setUser(user); }
রানটাইমে, অ্যাপটি UI-তে টেস্ট ব্যবহারকারীকে দেখায়। এছাড়াও, আপনি
LayoutInflater ব্যবহার করে
ভিউ পেতে পারেন, যেমনটি
নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
Kotlin
val binding: ActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater())
জাভা
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
আপনি যদি
Fragment,
ListView অথবা
RecyclerView
অ্যাডাপ্টারের মধ্যে ডেটা বাইন্ডিং আইটেম ব্যবহার করেন, তাহলে আপনি হয়ত
inflate()
বাইন্ডিং ক্লাসের পদ্ধতি অথবা
DataBindingUtil ক্লাস ব্যবহার করতে চাইবেন, যেমন
নিচের কোডের উদাহরণে দেখানো হয়েছে:
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
জাভা
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
এক্সপ্রেশন ল্যাঙ্গুয়েজ
একই ধরনের ফিচার
এক্সপ্রেশন ল্যাঙ্গুয়েজটি ম্যানেজ করা কোডে পাওয়া এক্সপ্রেশনের মতোই দেখতে। আপনি এক্সপ্রেশন ল্যাঙ্গুয়েজে নিম্নলিখিত অপারেটর ও কীওয়ার্ড ব্যবহার করতে পারবেন:
- গাণিতিক:
+ - / * % - স্ট্রিং কনক্যাটেনেশন:
+ - লজিক্যাল:
&& || - বাইনারি:
& | ^ - ইউনারি:
+ - ! ~ - শিফ্ট:
>> >>> << - তুলনা:
== > < >= <=(<-কে<হিসেবে এস্কেপ করতে হবে) instanceof- গ্রুপ করা:
() - লিটারেল, যেমন অক্ষর, স্ট্রিং, সংখ্যা,
null - কাস্ট করুন
- মেথড কল
- ফিল্ড অ্যাক্সেস
- এরে অ্যাক্সেস:
[] - টারনারি অপারেটর:
?:
কয়েকটি উদাহরণ দেখুন:
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
অপারেশন নেই
আপনি ম্যানেজ করা কোডে ব্যবহার করতে পারেন এমন এক্সপ্রেশন সিনট্যাক্সে নিম্নলিখিত অপারেশনগুলি নেই:
thissupernew- এক্সপ্লিসিট জেনেরিক ইনভোকেশন
Null coalescing অপারেটর
নাল কোয়ালিসিং অপারেটর (??) বাঁদিকের অপারেন্ড বেছে নেয় যদি সেটি null না হয়
অথবা ডানদিকেরটি বেছে নেয় যদি আগেরটি null হয়:
android:text="@{user.displayName ?? user.lastName}"
এটি কার্যকারিতার দিক থেকে নিম্নলিখিতটির সমতুল্য:
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
প্রপার্টি রেফারেন্স
কোনও এক্সপ্রেশন নিম্নলিখিত ফর্ম্যাট ব্যবহার করে ক্লাসের কোনও প্রপার্টিকে রেফারেন্স করতে পারে,
যা ফিল্ড, গেটার এবং
ObservableField
অবজেক্টের জন্য একই:
android:text="@{user.lastName}"
কোনও পয়েন্টার এক্সেপশন নেই
জেনারেট করা ডেটা বাইন্ডিং কোড অটোমেটিক null ভ্যালু চেক করে এবং
কোনও পয়েন্টার এক্সেপশন নেই। যেমন, @{user.name} এক্সপ্রেশনে, user যদি নাল হয়, তাহলে user.name-কে null-এর ডিফল্ট ভ্যালু অ্যাসাইন করা হয়। আপনি যদি user.age
রেফারেন্স করেন, যেখানে বয়স int ধরনের, তাহলে ডেটা বাইন্ডিং 0-এর
ডিফল্ট ভ্যালু ব্যবহার করে।
রেফারেন্স দেখুন
একটি এক্সপ্রেশন নিম্নলিখিত সিনট্যাক্স ব্যবহার করে আইডি দ্বারা লেআউটে অন্যান্য ভিউ রেফারেন্স করতে পারে:
android:text="@{exampleText.text}"
নিচের উদাহরণে, TextView ভিউ একই লেআউটে EditText ভিউকে
রেফারেন্স করে:
<EditText
android:id="@+id/example_text"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<TextView
android:id="@+id/example_output"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{exampleText.text}"/>
সংগ্রহ
সুবিধার জন্য [] অপারেটর ব্যবহার করে আপনি অ্যারে, তালিকা, স্পার্স তালিকা ও ম্যাপের মতো সাধারণ কালেকশন অ্যাক্সেস করতে পারবেন।
<data>
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<variable name="sparse" type="SparseArray<String>"/>
<variable name="map" type="Map<String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
...
android:text="@{list[index]}"
...
android:text="@{sparse[index]}"
...
android:text="@{map[key]}"
এছাড়াও, আপনি object.key নোটেশন ব্যবহার করে ম্যাপে কোনও ভ্যালু উল্লেখ করতে পারবেন। যেমন, আপনি আগের উদাহরণে @{map[key]}-এর পরিবর্তে
@{map.key} ব্যবহার করতে পারেন।
স্ট্রিং লিটারাল
আপনি অ্যাট্রিবিউট ভ্যালুর দু'পাশে সিঙ্গেল কোট ব্যবহার করতে পারেন, যা আপনাকে এক্সপ্রেশনে ডবল কোট ব্যবহার করতে দেয়, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
android:text='@{map["firstName"]}'
এছাড়াও, আপনি অ্যাট্রিবিউট ভ্যালুর দু'পাশে ডবল কোট ব্যবহার করতে পারেন। এটি করার সময়,
স্ট্রিং লিটারেল অবশ্যই ব্যাকটিক ` দিয়ে ঘিরে রাখতে হবে, যেমনটি
এখানে দেখানো হয়েছে:
android:text="@{map[`firstName`]}"
রিসোর্স
একটি এক্সপ্রেশন নিম্নলিখিত সিনট্যাক্স সহ অ্যাপ রিসোর্স রেফারেন্স করতে পারে:
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
প্যারামিটার প্রদান করে আপনি ফর্ম্যাট স্ট্রিং ও বহুবচন মূল্যায়ন করতে পারবেন:
android:text="@{@string/nameFormat(firstName, lastName)}"
android:text="@{@plurals/banana(bananaCount)}"
আপনি রিসোর্স প্যারামিটার হিসেবে প্রপার্টি রেফারেন্স এবং ভিউ রেফারেন্স পাস করতে পারেন:
android:text="@{@string/example_resource(user.lastName, exampleText.text)}"
বহুবচনে একাধিক প্যারামিটার থাকলে, সব প্যারামিটার পাস করুন:
Have an orange
Have %d oranges
android:text="@{@plurals/orange(orangeCount, orangeCount)}"
কিছু রিসোর্সের ক্ষেত্রে নির্দিষ্ট ধরনের মূল্যায়ন প্রয়োজন হয়, যেমনটি নিম্নলিখিত টেবিলে দেখানো হয়েছে:
| ধরন | সাধারণ রেফারেন্স | এক্সপ্রেশন রেফারেন্স |
|---|---|---|
String[] |
@array |
@stringArray |
int[] |
@array |
@intArray |
TypedArray |
@array |
@typedArray |
Animator |
@animator |
@animator |
StateListAnimator |
@animator |
@stateListAnimator |
color int |
@color |
@color |
ColorStateList |
@color |
@colorStateList |
ইভেন্ট হ্যান্ডলিং
ডেটা বাইন্ডিং আপনাকে ভিউ থেকে পাঠানো এক্সপ্রেশন হ্যান্ডলিং ইভেন্ট লিখতে দেয়—যেমন, onClick()
পদ্ধতি। ইভেন্ট অ্যাট্রিবিউটের নাম লিসেনার মেথডের নাম থেকে নির্ধারণ করা হয়,
তবে কিছু ব্যতিক্রম আছে। যেমন,
View.OnClickListener-এর
onClick() পদ্ধতি আছে, তাই এই ইভেন্টের অ্যাট্রিবিউট হল android:onClick।
ক্লিক ইভেন্টের জন্য কিছু বিশেষ ইভেন্ট হ্যান্ডলার আছে যেগুলির জন্য
android:onClick ছাড়া অন্য অ্যাট্রিবিউট প্রয়োজন হয় যাতে কোনও দ্বন্দ্ব না হয়। এই ধরনের সমস্যা এড়াতে আপনি
নিম্নলিখিত অ্যাট্রিবিউট ব্যবহার করতে পারেন:
| শ্রেণী | লিসনার সেটার | অ্যাট্রিবিউট |
|---|---|---|
SearchView |
setOnSearchClickListener(View.OnClickListener) |
android:onSearchClick |
ZoomControls |
setOnZoomInClickListener(View.OnClickListener) |
android:onZoomIn |
ZoomControls |
setOnZoomOutClickListener(View.OnClickListener) |
android:onZoomOut |
আপনি এই দুটি পদ্ধতি ব্যবহার করতে পারেন, যা নিম্নলিখিত বিভাগে বিস্তারিতভাবে বর্ণনা করা হয়েছে, একটি ইভেন্ট পরিচালনা করতে:
- পদ্ধতির রেফারেন্স: আপনার এক্সপ্রেশনে, আপনি
লিসেনার পদ্ধতির সিগনেচারের সাথে মানানসই পদ্ধতির রেফারেন্স দিতে পারেন। যখন
কোনও এক্সপ্রেশন পদ্ধতি রেফারেন্স মূল্যায়ন করে, তখন ডেটা বাইন্ডিং পদ্ধতি রেফারেন্স
এবং মালিক অবজেক্টকে একটি লিসেনারে মোড়ক করে এবং সেই লিসেনারকে
টার্গেট ভিউতে সেট করে। এক্সপ্রেশন
null-এ মূল্যায়ন করলে, ডেটা বাইন্ডিং লিসেনার তৈরি করে না এবং পরিবর্তেnullলিসেনার সেট করে। - লিসনার বাইন্ডিং: এগুলি হল ল্যাম্বডা এক্সপ্রেশন যা ইভেন্ট ঘটলে মূল্যায়ন করা হয়। ডেটা বাইন্ডিং সবসময় একটি লিসেনার তৈরি করে, যা এটি ভিউতে সেট করে। ইভেন্টটি ডিসপ্যাচ করা হলে, লিসেনার ল্যাম্বডা এক্সপ্রেশন মূল্যায়ন করে।
পদ্ধতির রেফারেন্স
আপনি সরাসরি হ্যান্ডলার পদ্ধতিতে ইভেন্ট বাইন্ড করতে পারবেন, ঠিক যেভাবে আপনি কোনও অ্যাক্টিভিটিতে
পদ্ধতিতে
android:onClick অ্যাসাইন
করতে পারেন। View onClick অ্যাট্রিবিউটের তুলনায়
একটি সুবিধা হল যে এক্সপ্রেশনটি কম্পাইল করার সময় প্রসেস করা হয়। তাই, পদ্ধতিটি না থাকলে বা এর
স্বাক্ষর ভুল হলে, আপনি কম্পাইল টাইম সংক্রান্ত সমস্যা পাবেন।
মেথড রেফারেন্স ও লিসেনার বাইন্ডিংয়ের মধ্যে প্রধান পার্থক্য হল, ইভেন্ট ট্রিগার হওয়ার সময় নয়, ডেটা বাউন্ড হওয়ার সময় আসল লিসেনার ইমপ্লিমেন্টেশন তৈরি হয়। ইভেন্ট ঘটার সময় আপনি এক্সপ্রেশন মূল্যায়ন করতে চাইলে, লিসেনার বাইন্ডিং ব্যবহার করুন।
কোনও ইভেন্টকে তার হ্যান্ডলারের সাথে অ্যাসাইন করতে, সাধারণ বাইন্ডিং এক্সপ্রেশন ব্যবহার করুন, যেখানে ভ্যালু হল কল করার জন্য মেথডের নাম। যেমন, নিম্নলিখিত উদাহরণ লেআউট ডেটা অবজেক্ট বিবেচনা করুন:
Kotlin
class MyHandlers { fun onClickFriend(view: View) { ... } }
জাভা
public class MyHandlers { public void onClickFriend(View view) { ... } }
বাইন্ডিং এক্সপ্রেশন, ভিউয়ের জন্য ক্লিক লিসনারকে onClickFriend() পদ্ধতিতে অ্যাসাইন করতে পারে,
যেমন:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.example.MyHandlers"/>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:onClick="@{handlers::onClickFriend}"/>
</LinearLayout>
</layout>
লিসনার বাইন্ডিং
লিসেনার বাইন্ডিং হল বাইন্ডিং এক্সপ্রেশন যা কোনও ইভেন্ট ঘটলে রান করে। এগুলি মেথড রেফারেন্সের মতো, তবে এগুলি আপনাকে ইচ্ছামতো ডেটা বাইন্ডিং এক্সপ্রেশন রান করতে দেয়। এই ফিচার Gradle ভার্সন ২.০ ও তার পরবর্তী যেকোনও ভার্সনের জন্য Android Gradle প্লাগ-ইনের সাথে উপলভ্য।
মেথড রেফারেন্সে, মেথডের প্যারামিটার অবশ্যই ইভেন্ট লিসেনারের প্যারামিটারের সাথে
ম্যাচ করতে হবে। লিসেনার বাইন্ডিংয়ে, শুধুমাত্র আপনার রিটার্ন ভ্যালু লিসেনারের প্রত্যাশিত রিটার্ন ভ্যালুর সাথে মিলতে হবে, যদি না এটি void প্রত্যাশা করে। যেমন, নিচের প্রেজেন্টার ক্লাসটি বিবেচনা করুন যাতে একটি onSaveClick()
মেথড আছে:
Kotlin
class Presenter { fun onSaveClick(task: Task){} }
জাভা
public class Presenter { public void onSaveClick(Task task){} }
আপনি নিম্নলিখিত উপায়ে onSaveClick() পদ্ধতিতে ক্লিক ইভেন্ট বাইন্ড করতে পারবেন:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="task" type="com.android.example.Task" />
<variable name="presenter" type="com.android.example.Presenter" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onSaveClick(task)}" />
</LinearLayout>
</layout>
কোনও এক্সপ্রেশনে কলব্যাক ব্যবহার করা হলে, ডেটা বাইন্ডিং অটোমেটিক প্রয়োজনীয় লিসেনার তৈরি করে এবং ইভেন্টের জন্য এটি রেজিস্টার করে। ভিউ ইভেন্ট ফায়ার করলে, ডেটা বাইন্ডিং প্রদত্ত এক্সপ্রেশন মূল্যায়ন করে। রেগুলার বাইন্ডিং এক্সপ্রেশনের মতো, এই লিসেনার এক্সপ্রেশন মূল্যায়ন করার সময় আপনি ডেটা বাইন্ডিংয়ের নাল ও থ্রেড নিরাপত্তা পান।
আগের উদাহরণে, onClick(View)-এ পাস করা view প্যারামিটার
সংজ্ঞায়িত করা নেই। লিসনার বাইন্ডিং লিসনার প্যারামিটারের জন্য দুটি বিকল্প প্রদান করে:
আপনি পদ্ধতির সমস্ত প্যারামিটার উপেক্ষা করতে পারেন বা তাদের সবকটির নাম দিতে পারেন। আপনি যদি
প্যারামিটারের নাম দিতে চান, তাহলে আপনার এক্সপ্রেশনে সেগুলি ব্যবহার করতে পারেন। যেমন, আপনি
আগের এক্সপ্রেশনটি এইভাবে লিখতে পারেন:
android:onClick="@{(view) -> presenter.onSaveClick(task)}"
আপনি যদি এক্সপ্রেশনে প্যারামিটার ব্যবহার করতে চান, তাহলে আপনি নিম্নলিখিত উপায়ে তা করতে পারেন:
Kotlin
class Presenter { fun onSaveClick(view: View, task: Task){} }
জাভা
public class Presenter { public void onSaveClick(View view, Task task){} }
android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
এবং আপনি একাধিক প্যারামিটার সহ একটি ল্যাম্বডা এক্সপ্রেশন ব্যবহার করতে পারেন:
Kotlin
class Presenter { fun onCompletedChanged(task: Task, completed: Boolean){} }
জাভা
public class Presenter { public void onCompletedChanged(Task task, boolean completed){} }
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
আপনি যে ইভেন্ট শুনছেন সেটি যদি এমন কোনও ভ্যালু রিটার্ন করে যার ধরন void নয়, তাহলে আপনার
এক্সপ্রেশনকেও একই ধরনের ভ্যালু রিটার্ন করতে হবে। যেমন, আপনি যদি টাচ করে ধরে থাকা (লং ক্লিক) ইভেন্ট শুনতে চান, তাহলে আপনার এক্সপ্রেশনকে অবশ্যই একটি বুলিয়ান রিটার্ন করতে হবে।
Kotlin
class Presenter { fun onLongClick(view: View, task: Task): Boolean { } }
জাভা
public class Presenter { public boolean onLongClick(View view, Task task) { } }
android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"
null অবজেক্টের কারণে এক্সপ্রেশন মূল্যায়ন করা না গেলে, ডেটা বাইন্ডিং সেই ধরনের জন্য
ডিফল্ট ভ্যালু ফিরিয়ে দেয়, যেমন রেফারেন্স ধরনের জন্য null, int-এর জন্য
0 অথবা boolean-এর জন্য false।
আপনাকে যদি প্রেডিকেট সহ কোনও এক্সপ্রেশন ব্যবহার করতে হয়—যেমন, টারনারি—আপনি প্রতীক হিসেবে void ব্যবহার করতে পারেন:
android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
জটিল লিসনার এড়িয়ে চলুন
লিসনার এক্সপ্রেশন শক্তিশালী এবং আপনার কোড পড়া সহজ করে তুলতে পারে। অন্যদিকে, জটিল এক্সপ্রেশন সহ লিসেনার আপনার লেআউটকে আরও কঠিন করে তোলে। আপনার UI থেকে কলব্যাক পদ্ধতিতে উপলভ্য ডেটা পাস করার মতো আপনার এক্সপ্রেশন সহজ রাখুন। লিসনার এক্সপ্রেশন থেকে কলব্যাক মেথড কল করে তার মধ্যে যেকোনও বিজনেস লজিক প্রয়োগ করুন।
ইমপোর্ট, ভেরিয়েবেল ও অন্তর্ভুক্ত করা
ডেটা বাইন্ডিং লাইব্রেরি ইমপোর্ট, ভেরিয়েবেল ও অন্তর্ভুক্তির মতো ফিচার প্রদান করে। ইমপোর্ট করার ফলে আপনার লেআউট ফাইলের মধ্যে সহজে রেফারেন্স করা যায় এমন ক্লাস তৈরি হয়। ভেরিয়েবল আপনাকে এমন একটি প্রপার্টি বর্ণনা করতে দেয় যা বাইন্ডিং এক্সপ্রেশনে ব্যবহার করা যেতে পারে। আপনার অ্যাপ জুড়ে জটিল লেআউট আবার ব্যবহার করার সুবিধা অন্তর্ভুক্ত করে।
ইমপোর্ট
ইমপোর্ট করার মাধ্যমে আপনি লেআউট ফাইলের মধ্যে ক্লাস রেফারেন্স করতে পারবেন, যেমন ম্যানেজ করা কোডে করা হয়।
আপনি data এলিমেন্টের মধ্যে শূন্য বা তার বেশি import এলিমেন্ট ব্যবহার করতে পারবেন। নিম্নলিখিত
কোডের উদাহরণ লেআউট ফাইলে View ক্লাস ইমপোর্ট করে:
<data>
<import type="android.view.View"/>
</data>
View ক্লাস ইমপোর্ট করলে, আপনি নিজের বাইন্ডিং এক্সপ্রেশন থেকে এটি রেফারেন্স করতে পারবেন।
View ক্লাসের
VISIBLE এবং
GONE কনস্ট্যান্ট কীভাবে রেফারেন্স করতে হয় তা নিম্নলিখিত উদাহরণ থেকে দেখুন:
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>
অ্যালিয়াস টাইপ করুন
ক্লাসের নাম নিয়ে কোনও সমস্যা হলে, আপনি একটি ক্লাসের নাম পরিবর্তন করে অন্য নাম
দিতে পারেন। নিম্নলিখিত উদাহরণে com.example.real.estate প্যাকেজে View ক্লাসের নাম পরিবর্তন করে
Vista করা হয়েছে:
<import type="android.view.View"/>
<import type="com.example.real.estate.View"
alias="Vista"/>
তারপর আপনি লেআউট ফাইলের মধ্যে com.example.real.estate.View-এর রেফারেন্স হিসেবে Vista এবং android.view.View-এর রেফারেন্স হিসেবে View
ব্যবহার করতে পারবেন।
অন্যান্য ক্লাস ইমপোর্ট করুন
আপনি ভেরিয়েবল ও এক্সপ্রেশনে ইম্পোর্ট করা ধরনকে টাইপ রেফারেন্স হিসেবে ব্যবহার করতে পারবেন। নিম্নলিখিত
উদাহরণে দেখানো হয়েছে যে কীভাবে User এবং List ভেরিয়েবলের ধরন হিসেবে ব্যবহার করা হয়:
<data>
<import type="com.example.User"/>
<import type="java.util.List"/>
<variable name="user" type="User"/>
<variable name="userList" type="List<User>"/>
</data>
আপনি এক্সপ্রেশনের অংশ কাস্ট করতে ইমপোর্ট করা ধরন ব্যবহার করতে পারেন। নিচে দেওয়া
উদাহরণে connection প্রপার্টিকে User-এর ধরন হিসেবে কাস্ট করা হয়েছে:
<TextView
android:text="@{((User)(user.connection)).lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
এক্সপ্রেশনে স্ট্যাটিক ফিল্ড ও মেথড রেফার করার সময় আপনি ইমপোর্ট করা টাইপও ব্যবহার করতে পারবেন। নিম্নলিখিত কোড MyStringUtils ক্লাস ইমপোর্ট করে এবং এর capitalize পদ্ধতিকে
রেফারেন্স করে:
<data>
<import type="com.example.MyStringUtils"/>
<variable name="user" type="com.example.User"/>
</data>
…
<TextView
android:text="@{MyStringUtils.capitalize(user.lastName)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
ম্যানেজ করা কোডের মতোই, java.lang.* অটোমেটিক ইমপোর্ট করা হয়।
ভেরিয়েবল
আপনি data এলিমেন্টের মধ্যে একাধিক variable এলিমেন্ট ব্যবহার করতে পারবেন। প্রতিটি
variable এলিমেন্ট এমন একটি প্রপার্টি বর্ণনা করে যা লেআউট ফাইলে বাইন্ডিং এক্সপ্রেশনে ব্যবহার করার জন্য
লেআউটে সেট করা যেতে পারে। নিচের উদাহরণে user, image এবং note ভেরিয়েবেল
ঘোষণা করা হয়েছে:
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
কম্পাইল করার সময় ভেরিয়েবেলের ধরন পরীক্ষা করা হয়, তাই কোনও ভেরিয়েবেল
Observable প্রয়োগ করলে বা
পর্যবেক্ষণযোগ্য সংগ্রহ হলে,
সেটি অবশ্যই ধরনের মধ্যে প্রতিফলিত হতে হবে। ভেরিয়েবেলটি যদি এমন কোনও মূল ক্লাস বা ইন্টারফেস হয়
যা Observable ইন্টারফেস প্রয়োগ করে না, তাহলে ভেরিয়েবেলগুলি পর্যবেক্ষণ করা
হয় না।
বিভিন্ন কনফিগারেশনের জন্য আলাদা লেআউট ফাইল থাকলে (যেমন, ল্যান্ডস্কেপ বা পোর্ট্রেট), ভেরিয়েবলগুলি একত্রিত করা হয়। এইসব লেআউট ফাইলের মধ্যে পরস্পরবিরোধী ভেরিয়েবেল সংজ্ঞা থাকলে চলবে না।
জেনারেট করা বাইন্ডিং ক্লাসে প্রতিটি বর্ণিত ভেরিয়েবলের জন্য একটি সেটার ও গেটার থাকে। সেটার কল না করা পর্যন্ত ভেরিয়েবল ডিফল্ট ম্যানেজ করা কোড ভ্যালু নেয়—রেফারেন্স টাইপের জন্য null, int-এর জন্য 0, boolean-এর জন্য false ইত্যাদি।
প্রয়োজন অনুযায়ী বাইন্ডিং এক্সপ্রেশনে ব্যবহার করার জন্য context নামের একটি বিশেষ ভেরিয়েবল
জেনারেট করা হয়। context-এর ভ্যালু হল রুট ভিউয়ের
getContext() পদ্ধতি থেকে পাওয়া
Context অবজেক্ট। context ভেরিয়েবলটি সেই নামের একটি স্পষ্ট ভেরিয়েবল ঘোষণা দ্বারা ওভাররাইড করা হয়েছে।
এতে অন্তর্ভুক্ত
আপনি অন্তর্ভুক্ত লেআউটের বাইন্ডিংয়ে ভেরিয়েবল পাস করতে পারবেন। এর জন্য আপনাকে কন্টেনিং লেআউট থেকে অ্যাপ নেমস্পেস এবং অ্যাট্রিবিউটে ভেরিয়েবলের নাম ব্যবহার করতে হবে। নিচে
দেওয়া উদাহরণে name.xml এবং
contact.xml লেআউট ফাইল থেকে অন্তর্ভুক্ত user ভেরিয়েবল দেখানো হয়েছে:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</LinearLayout>
</layout>
ডেটা বাইন্ডিং, মার্জ এলিমেন্টের সরাসরি চাইল্ড হিসেবে ইনক্লুডকে সাপোর্ট করে না। যেমন, নিম্নলিখিত লেআউট কাজ করে না:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<merge><!-- Doesn't work -->
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</merge>
</layout>
অতিরিক্ত রিসোর্স
ডেটা বাইন্ডিং সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন।