অ্যান্ড্রয়েডে, আপনার অ্যাপ্লিকেশনের সাথে ব্যবহারকারীর মিথস্ক্রিয়া থেকে ইভেন্টগুলিকে আটকানোর একাধিক উপায় রয়েছে৷ আপনার ইউজার ইন্টারফেসের মধ্যে ইভেন্টগুলি বিবেচনা করার সময়, পদ্ধতিটি হল নির্দিষ্ট ভিউ অবজেক্ট থেকে ইভেন্টগুলি ক্যাপচার করা যার সাথে ব্যবহারকারী ইন্টারঅ্যাক্ট করে। ভিউ ক্লাস এটি করার উপায় সরবরাহ করে।
বিভিন্ন ভিউ ক্লাসের মধ্যে যা আপনি আপনার লেআউট রচনা করতে ব্যবহার করবেন, আপনি অনেকগুলি সর্বজনীন কলব্যাক পদ্ধতি লক্ষ্য করতে পারেন যা UI ইভেন্টগুলির জন্য দরকারী বলে মনে হয়৷ এই পদ্ধতিগুলিকে অ্যান্ড্রয়েড ফ্রেমওয়ার্ক দ্বারা বলা হয় যখন সেই বস্তুতে সংশ্লিষ্ট ক্রিয়া ঘটে। উদাহরণস্বরূপ, যখন একটি ভিউ (যেমন একটি বোতাম) স্পর্শ করা হয়, তখন সেই বস্তুটিতে onTouchEvent()
পদ্ধতিটি কল করা হয়। যাইহোক, এটিকে বাধা দেওয়ার জন্য, আপনাকে অবশ্যই ক্লাস প্রসারিত করতে হবে এবং পদ্ধতিটি ওভাররাইড করতে হবে। যাইহোক, এই ধরনের ইভেন্ট পরিচালনা করার জন্য প্রতিটি ভিউ অবজেক্টকে প্রসারিত করা ব্যবহারিক হবে না। এই কারণেই ভিউ ক্লাসে কলব্যাক সহ নেস্টেড ইন্টারফেসের একটি সংগ্রহ রয়েছে যা আপনি আরও সহজে সংজ্ঞায়িত করতে পারেন। ইভেন্ট লিসেনার নামে পরিচিত এই ইন্টারফেসগুলি হল আপনার UI এর সাথে ব্যবহারকারীর মিথস্ক্রিয়া ক্যাপচার করার জন্য আপনার টিকিট।
যদিও আপনি ব্যবহারকারীর মিথস্ক্রিয়া শোনার জন্য ইভেন্ট শ্রোতাদের আরও বেশি ব্যবহার করবেন, এমন একটি সময় আসতে পারে যখন আপনি একটি কাস্টম উপাদান তৈরি করার জন্য একটি ভিউ ক্লাস প্রসারিত করতে চান। সম্ভবত আপনি আরও অভিনব কিছু করতে Button
ক্লাস প্রসারিত করতে চান। এই ক্ষেত্রে, আপনি ক্লাস ইভেন্ট হ্যান্ডলার ব্যবহার করে আপনার ক্লাসের জন্য ডিফল্ট ইভেন্ট আচরণ সংজ্ঞায়িত করতে সক্ষম হবেন।
অনুষ্ঠান শ্রোতা
একটি ইভেন্ট লিসেনার হল View
ক্লাসের একটি ইন্টারফেস যাতে একটি একক কলব্যাক পদ্ধতি থাকে। এই পদ্ধতিগুলিকে অ্যান্ড্রয়েড ফ্রেমওয়ার্ক দ্বারা কল করা হবে যখন শ্রোতাকে নিবন্ধিত করা হয়েছে এমন দৃশ্যটি UI-তে আইটেমের সাথে ব্যবহারকারীর মিথস্ক্রিয়া দ্বারা ট্রিগার করা হয়।
ইভেন্ট শ্রোতা ইন্টারফেস নিম্নলিখিত কলব্যাক পদ্ধতি অন্তর্ভুক্ত:
-
onClick()
-
View.OnClickListener
থেকে। এটি বলা হয় যখন ব্যবহারকারী হয় আইটেমটি স্পর্শ করেন (যখন স্পর্শ মোডে), অথবা নেভিগেশন-কি বা ট্র্যাকবল দিয়ে আইটেমটির উপর ফোকাস করেন এবং উপযুক্ত "এন্টার" কী টিপে বা ট্র্যাকবলে চাপ দেন। -
onLongClick()
-
View.OnLongClickListener
থেকে। এটিকে বলা হয় যখন ব্যবহারকারী আইটেমটিকে স্পর্শ করে এবং ধরে রাখে (যখন স্পর্শ মোডে থাকে), অথবা নেভিগেশন-কি বা ট্র্যাকবল দিয়ে আইটেমের উপর ফোকাস করে এবং উপযুক্ত "এন্টার" কী টিপে এবং ধরে রাখে বা ট্র্যাকবলে চেপে ধরে রাখে ( এক সেকেন্ডের জন্য)। -
onFocusChange()
-
View.OnFocusChangeListener
থেকে। এটি বলা হয় যখন ব্যবহারকারী নেভিগেশন-কী বা ট্র্যাকবল ব্যবহার করে আইটেমটির উপর বা দূরে যান। -
onKey()
-
View.OnKeyListener
থেকে। এটি বলা হয় যখন ব্যবহারকারী আইটেমের উপর দৃষ্টি নিবদ্ধ করে এবং ডিভাইসে একটি হার্ডওয়্যার কী টিপে বা রিলিজ করে। -
onTouch()
-
View.OnTouchListener
থেকে। এটি বলা হয় যখন ব্যবহারকারী একটি স্পর্শ ইভেন্ট হিসাবে যোগ্য একটি ক্রিয়া সম্পাদন করে, যার মধ্যে একটি প্রেস, একটি রিলিজ, বা স্ক্রিনে (আইটেমের সীমার মধ্যে) যেকোন নড়াচড়া অঙ্গভঙ্গি রয়েছে। -
onCreateContextMenu()
-
View.OnCreateContextMenuListener
থেকে। এটি বলা হয় যখন একটি প্রসঙ্গ মেনু তৈরি করা হচ্ছে (একটি স্থায়ী "দীর্ঘ ক্লিক" এর ফলাফল হিসাবে)। মেনু বিকাশকারী গাইডে প্রসঙ্গ মেনু নিয়ে আলোচনা দেখুন।
এই পদ্ধতিগুলি তাদের নিজ নিজ ইন্টারফেসের একমাত্র বাসিন্দা। এই পদ্ধতিগুলির মধ্যে একটিকে সংজ্ঞায়িত করতে এবং আপনার ইভেন্টগুলি পরিচালনা করতে, আপনার কার্যকলাপে নেস্টেড ইন্টারফেসটি প্রয়োগ করুন বা এটিকে একটি বেনামী ক্লাস হিসাবে সংজ্ঞায়িত করুন৷ তারপর, সংশ্লিষ্ট View.set...Listener()
পদ্ধতিতে আপনার বাস্তবায়নের একটি উদাহরণ পাস করুন। (যেমন,
কল করুন এবং এটিকে আপনার setOnClickListener()
OnClickListener
এর বাস্তবায়ন পাস করুন।)
নীচের উদাহরণটি দেখায় কিভাবে একটি বোতামের জন্য একটি অন-ক্লিক শ্রোতা নিবন্ধন করতে হয়৷
কোটলিন
protected void onCreate(savedValues: Bundle) { ... val button: Button = findViewById(R.id.corky) // Register the onClick listener with the implementation above button.setOnClickListener { view -> // do something when the button is clicked } ... }
জাভা
// Create an anonymous implementation of OnClickListener private OnClickListener corkyListener = new OnClickListener() { public void onClick(View v) { // do something when the button is clicked } }; protected void onCreate(Bundle savedValues) { ... // Capture our button from layout Button button = (Button)findViewById(R.id.corky); // Register the onClick listener with the implementation above button.setOnClickListener(corkyListener); ... }
আপনার কার্যকলাপের অংশ হিসাবে OnClickListener প্রয়োগ করা আরও সুবিধাজনক বলে মনে হতে পারে। এটি অতিরিক্ত ক্লাস লোড এবং বস্তু বরাদ্দ এড়াবে। যেমন:
কোটলিন
class ExampleActivity : Activity(), OnClickListener { protected fun onCreate(savedValues: Bundle) { val button: Button = findViewById(R.id.corky) button.setOnClickListener(this) } // Implement the OnClickListener callback fun onClick(v: View) { // do something when the button is clicked } }
জাভা
public class ExampleActivity extends Activity implements OnClickListener { protected void onCreate(Bundle savedValues) { ... Button button = (Button)findViewById(R.id.corky); button.setOnClickListener(this); } // Implement the OnClickListener callback public void onClick(View v) { // do something when the button is clicked } ... }
লক্ষ্য করুন যে উপরের উদাহরণে onClick()
কলব্যাকের কোনো রিটার্ন মান নেই, তবে কিছু অন্যান্য ইভেন্ট লিসেনার পদ্ধতিতে অবশ্যই একটি বুলিয়ান রিটার্ন করা উচিত। কারণ ঘটনার উপর নির্ভর করে। যারা করেন তাদের জন্য, এখানে কেন:
-
- আপনি ইভেন্টটি গ্রাস করেছেন কিনা তা নির্দেশ করতে এটি একটি বুলিয়ান প্রদান করে এবং এটিকে আরও বাড়ানো উচিত নয়। অর্থাৎ, আপনি ইভেন্ট পরিচালনা করেছেন তা নির্দেশ করার জন্য সত্যে ফিরে যান এবং এটি এখানে থামানো উচিত; আপনি যদি এটি পরিচালনা না করে থাকেন তবে মিথ্যা ফেরত দিন এবং/অথবা ইভেন্টটি অন্য কোনো অন-ক্লিক শ্রোতাদের কাছে চালিয়ে যাওয়া উচিত।onLongClick()
-
- আপনি ইভেন্টটি গ্রহণ করেছেন কিনা তা নির্দেশ করতে এটি একটি বুলিয়ান প্রদান করে এবং এটিকে আরও বাড়ানো উচিত নয়। অর্থাৎ, আপনি ইভেন্ট পরিচালনা করেছেন তা নির্দেশ করার জন্য সত্যে ফিরে যান এবং এটি এখানে থামানো উচিত; আপনি যদি এটি পরিচালনা না করে থাকেন তবে মিথ্যা ফেরত দিন এবং/অথবা ইভেন্টটি অন্য কোন অন-কী শ্রোতাদের কাছে চালিয়ে যাওয়া উচিত।onKey()
-
- আপনার শ্রোতা এই ইভেন্টটি ব্যবহার করে কিনা তা নির্দেশ করতে এটি একটি বুলিয়ান প্রদান করে। গুরুত্বপূর্ণ বিষয় হল এই ইভেন্টে একাধিক অ্যাকশন থাকতে পারে যা একে অপরকে অনুসরণ করে। সুতরাং, ডাউন অ্যাকশন ইভেন্টটি প্রাপ্ত হলে আপনি যদি মিথ্যা ফেরত দেন, তাহলে আপনি ইঙ্গিত করেন যে আপনি ইভেন্টটি গ্রহণ করেননি এবং এই ইভেন্টের পরবর্তী ক্রিয়াগুলিতেও আগ্রহী নন। এইভাবে, আপনাকে ইভেন্টের মধ্যে অন্য কোনো অ্যাকশনের জন্য ডাকা হবে না, যেমন আঙুলের অঙ্গভঙ্গি, বা ইভেন্ট আপ অ্যাকশন ইভেন্ট।onTouch()
মনে রাখবেন যে হার্ডওয়্যার কী ইভেন্টগুলি সর্বদা বর্তমানে ফোকাসে থাকা ভিউতে সরবরাহ করা হয়। তারা যথাযথ গন্তব্যে না পৌঁছানো পর্যন্ত ভিউ অনুক্রমের শীর্ষ থেকে শুরু করে এবং তারপর নিচে পাঠানো হয়। যদি আপনার ভিউ (অথবা আপনার ভিউয়ের সন্তানের) বর্তমানে ফোকাস থাকে, তাহলে আপনি
পদ্ধতির মাধ্যমে ইভেন্ট ভ্রমণ দেখতে পারেন। আপনার ভিউয়ের মাধ্যমে মূল ইভেন্টগুলি ক্যাপচার করার বিকল্প হিসাবে, আপনি dispatchKeyEvent()
এবং onKeyDown()
এর মাধ্যমে আপনার কার্যকলাপের ভিতরের সমস্ত ইভেন্টও পেতে পারেন।onKeyUp()
এছাড়াও, আপনার অ্যাপ্লিকেশনের জন্য পাঠ্য ইনপুট সম্পর্কে চিন্তা করার সময়, মনে রাখবেন যে অনেক ডিভাইসে শুধুমাত্র সফ্টওয়্যার ইনপুট পদ্ধতি রয়েছে৷ এই ধরনের পদ্ধতিগুলি কী-ভিত্তিক হওয়ার প্রয়োজন নেই; কেউ কেউ ভয়েস ইনপুট, হাতের লেখা ইত্যাদি ব্যবহার করতে পারে। এমনকি যদি একটি ইনপুট পদ্ধতি একটি কীবোর্ড-সদৃশ ইন্টারফেস উপস্থাপন করে, এটি সাধারণত
ইভেন্টের পরিবারকে ট্রিগার করবে না । আপনার কখনই এমন একটি UI তৈরি করা উচিত নয় যাতে নিয়ন্ত্রিত করার জন্য নির্দিষ্ট কী প্রেসের প্রয়োজন হয় যদি না আপনি আপনার অ্যাপ্লিকেশনটিকে একটি হার্ডওয়্যার কীবোর্ড সহ ডিভাইসগুলিতে সীমাবদ্ধ করতে চান৷ বিশেষ করে, ব্যবহারকারী যখন রিটার্ন কী টিপে ইনপুট যাচাই করতে এই পদ্ধতিগুলির উপর নির্ভর করবেন না; পরিবর্তে, আপনার অ্যাপ্লিকেশান কীভাবে প্রতিক্রিয়া দেখাবে তা সংকেত দিতে onKeyDown()
IME_ACTION_DONE
এর মতো ক্রিয়াগুলি ব্যবহার করুন, যাতে এটি একটি অর্থপূর্ণ উপায়ে এর UI পরিবর্তন করতে পারে৷ একটি সফ্টওয়্যার ইনপুট পদ্ধতি কীভাবে কাজ করবে সে সম্পর্কে অনুমান এড়িয়ে চলুন এবং আপনার অ্যাপ্লিকেশনে ইতিমধ্যে ফর্ম্যাট করা পাঠ্য সরবরাহ করার জন্য এটিকে বিশ্বাস করুন।
দ্রষ্টব্য: অ্যান্ড্রয়েড প্রথমে ইভেন্ট হ্যান্ডলারদের কল করবে এবং তারপর ক্লাস ডেফিনিশন দ্বিতীয় থেকে উপযুক্ত ডিফল্ট হ্যান্ডলারদের কল করবে। যেমন, এই ইভেন্ট শ্রোতাদের থেকে সত্য ফিরে আসা অন্যান্য ইভেন্ট শ্রোতাদের কাছে ইভেন্টের প্রচার বন্ধ করবে এবং ভিউতে ডিফল্ট ইভেন্ট হ্যান্ডলারে কলব্যাককে ব্লক করবে। তাই নিশ্চিত হোন যে আপনি ইভেন্টটি শেষ করতে চান যখন আপনি সত্য ফিরে আসবেন।
ইভেন্ট হ্যান্ডলার
আপনি যদি ভিউ থেকে একটি কাস্টম উপাদান তৈরি করছেন, তাহলে আপনি ডিফল্ট ইভেন্ট হ্যান্ডলার হিসাবে ব্যবহৃত বেশ কয়েকটি কলব্যাক পদ্ধতি সংজ্ঞায়িত করতে সক্ষম হবেন। কাস্টম ভিউ উপাদান সম্পর্কে নথিতে, আপনি ইভেন্ট পরিচালনার জন্য ব্যবহৃত কিছু সাধারণ কলব্যাক শিখবেন, যার মধ্যে রয়েছে:
-
- যখন একটি নতুন কী ইভেন্ট ঘটে তখন বলা হয়।onKeyDown(int, KeyEvent)
-
- যখন একটি কী আপ ইভেন্ট হয় তখন কল করা হয়।onKeyUp(int, KeyEvent)
-
- যখন একটি ট্র্যাকবল মোশন ইভেন্ট ঘটে তখন বলা হয়।onTrackballEvent(MotionEvent)
-
- যখন একটি টাচ স্ক্রীন মোশন ইভেন্ট ঘটে তখন বলা হয়।onTouchEvent(MotionEvent)
-
- যখন ভিউ ফোকাস লাভ করে বা হারায় তখন বলা হয়।onFocusChanged(boolean, int, Rect)
আরও কিছু পদ্ধতি রয়েছে যা আপনার সচেতন হওয়া উচিত, যেগুলি ভিউ ক্লাসের অংশ নয়, তবে আপনি যেভাবে ইভেন্টগুলি পরিচালনা করতে সক্ষম হন তা সরাসরি প্রভাবিত করতে পারে। সুতরাং, একটি লেআউটের ভিতরে আরও জটিল ইভেন্টগুলি পরিচালনা করার সময়, এই অন্যান্য পদ্ধতিগুলি বিবেচনা করুন:
-
- এটি আপনারActivity.dispatchTouchEvent(MotionEvent)
Activity
সমস্ত টাচ ইভেন্টকে উইন্ডোতে পাঠানোর আগে আটকাতে দেয়। -
- এটি একটিViewGroup.onInterceptTouchEvent(MotionEvent)
ViewGroup
ইভেন্টগুলি দেখার অনুমতি দেয় যেহেতু সেগুলি চাইল্ড ভিউতে পাঠানো হয়৷ -
- এটিকেViewParent.requestDisallowInterceptTouchEvent(boolean)
এর সাথে স্পর্শ ইভেন্টগুলিকে আটকানো উচিত নয় তা নির্দেশ করার জন্য এটিকে একটি অভিভাবক ভিউতে কল করুন।onInterceptTouchEvent(MotionEvent)
টাচ মোড
যখন একজন ব্যবহারকারী নির্দেশমূলক কী বা একটি ট্র্যাকবল দিয়ে একটি ব্যবহারকারীর ইন্টারফেস নেভিগেট করেন, তখন কর্মযোগ্য আইটেমগুলিতে (যেমন বোতাম) ফোকাস করা প্রয়োজন যাতে ব্যবহারকারী দেখতে পারে কী ইনপুট গ্রহণ করবে। ডিভাইসটিতে স্পর্শ করার ক্ষমতা থাকলে, এবং ব্যবহারকারী এটিকে স্পর্শ করে ইন্টারফেসের সাথে ইন্টারঅ্যাক্ট করতে শুরু করে, তাহলে আইটেমগুলিকে হাইলাইট করার বা একটি নির্দিষ্ট দৃশ্যে ফোকাস দেওয়ার আর প্রয়োজন নেই। সুতরাং, "টাচ মোড" নামে মিথস্ক্রিয়া জন্য একটি মোড আছে।
একটি স্পর্শ-সক্ষম ডিভাইসের জন্য, ব্যবহারকারী একবার স্ক্রীন স্পর্শ করলে, ডিভাইসটি স্পর্শ মোডে প্রবেশ করবে। এখন থেকে, শুধুমাত্র যে ভিউগুলির জন্য isFocusableInTouchMode()
সত্য সেগুলিই ফোকাসযোগ্য হবে, যেমন টেক্সট এডিটিং উইজেট৷ অন্যান্য ভিউ যা স্পর্শযোগ্য, যেমন বোতাম, স্পর্শ করা হলে ফোকাস নেবে না; চাপ দিলে তারা কেবল তাদের অন-ক্লিক শ্রোতাদের গুলি করে দেবে।
যে কোনো সময় একজন ব্যবহারকারী একটি দিকনির্দেশক কী আঘাত করে বা ট্র্যাকবল দিয়ে স্ক্রোল করে, ডিভাইসটি স্পর্শ মোড থেকে প্রস্থান করবে এবং ফোকাস নেওয়ার জন্য একটি দৃশ্য খুঁজে পাবে। এখন, ব্যবহারকারী স্ক্রীন স্পর্শ না করেই ব্যবহারকারী ইন্টারফেসের সাথে ইন্টারঅ্যাক্ট করা আবার শুরু করতে পারে।
টাচ মোড অবস্থা সমগ্র সিস্টেম জুড়ে রক্ষণাবেক্ষণ করা হয় (সমস্ত উইন্ডো এবং কার্যকলাপ)। বর্তমান অবস্থা জানতে, ডিভাইসটি বর্তমানে টাচ মোডে আছে কিনা তা দেখতে আপনি isInTouchMode()
কল করতে পারেন।
হ্যান্ডলিং ফোকাস
ফ্রেমওয়ার্ক ব্যবহারকারীর ইনপুটের প্রতিক্রিয়া হিসাবে রুটিন ফোকাস আন্দোলন পরিচালনা করবে। ভিউগুলি সরানো বা লুকানো বা নতুন ভিউ উপলব্ধ হওয়ার সাথে সাথে ফোকাস পরিবর্তন করা এর মধ্যে রয়েছে। দর্শনগুলি
পদ্ধতির মাধ্যমে ফোকাস নিতে তাদের ইচ্ছুকতা নির্দেশ করে। একটি ভিউ ফোকাস নিতে পারে কিনা তা পরিবর্তন করতে, isFocusable()
কল করুন। স্পর্শ মোডে থাকাকালীন, আপনি প্রশ্ন করতে পারেন যে একটি ভিউ setFocusable()
এর সাথে ফোকাস করতে দেয় কিনা। আপনি isFocusableInTouchMode()
দিয়ে এটি পরিবর্তন করতে পারেন।setFocusableInTouchMode()
Android 9 (API স্তর 28) বা উচ্চতর চলমান ডিভাইসগুলিতে, কার্যকলাপগুলি প্রাথমিক ফোকাস নির্ধারণ করে না। পরিবর্তে, আপনি স্পষ্টভাবে প্রাথমিক ফোকাস অনুরোধ করতে হবে, যদি ইচ্ছা হয়.
ফোকাস আন্দোলন একটি অ্যালগরিদমের উপর ভিত্তি করে যা একটি নির্দিষ্ট দিক থেকে নিকটতম প্রতিবেশীকে খুঁজে পায়। বিরল ক্ষেত্রে, ডিফল্ট অ্যালগরিদম বিকাশকারীর উদ্দেশ্যমূলক আচরণের সাথে মেলে না। এই পরিস্থিতিতে, আপনি লেআউট ফাইলে নিম্নলিখিত XML বৈশিষ্ট্যগুলির সাথে স্পষ্ট ওভাররাইড প্রদান করতে পারেন: nextFocusDown , nextFocusLeft , nextFocusRight , এবং nextFocusUp । যে ভিউ থেকে ফোকাস চলে যাচ্ছে তাতে এই অ্যাট্রিবিউটগুলির একটি যোগ করুন। যে ভিউয়ের আইডিতে ফোকাস দেওয়া উচিত তার জন্য অ্যাট্রিবিউটের মান নির্ধারণ করুন। যেমন:
<LinearLayout android:orientation="vertical" ... > <Button android:id="@+id/top" android:nextFocusUp="@+id/bottom" ... /> <Button android:id="@+id/bottom" android:nextFocusDown="@+id/top" ... /> </LinearLayout>
সাধারণত, এই উল্লম্ব বিন্যাসে, প্রথম বোতাম থেকে নেভিগেট করা কোথাও যাবে না বা দ্বিতীয় বোতাম থেকে নিচে নেভিগেট করবে না। এখন যেহেতু উপরের বোতামটি নীচেরটিকে nextFocusUp (এবং এর বিপরীতে) হিসাবে সংজ্ঞায়িত করেছে, নেভিগেশন ফোকাসটি উপরে থেকে নীচে এবং নীচে থেকে উপরে যাবে৷
আপনি যদি আপনার UI-তে একটি ভিউকে ফোকাসযোগ্য হিসাবে ঘোষণা করতে চান (যখন এটি ঐতিহ্যগতভাবে না হয়), আপনার লেআউট ঘোষণায় ভিউতে android:focusable
XML অ্যাট্রিবিউট যোগ করুন। মান true সেট করুন. আপনি android:focusableInTouchMode
এর সাথে টাচ মোডে থাকাকালীন একটি ভিউকে ফোকাসযোগ্য হিসাবে ঘোষণা করতে পারেন।
ফোকাস নেওয়ার জন্য একটি নির্দিষ্ট ভিউকে অনুরোধ করতে,
কল করুন।requestFocus()
ফোকাস ইভেন্টগুলি শুনতে (যখন একটি ভিউ ফোকাস গ্রহণ করে বা হারায় তখন অবহিত করা হয়),
ব্যবহার করুন, যেমন ইভেন্ট শ্রোতা বিভাগে আলোচনা করা হয়েছে। onFocusChange()