ইনপুট ইভেন্ট ওভারভিউ

কম্পোজ পদ্ধতিটি চেষ্টা করুন
জেটপ্যাক কম্পোজ হলো অ্যান্ড্রয়েডের জন্য প্রস্তাবিত UI টুলকিট। কম্পোজে কীভাবে টাচ ও ইনপুট ব্যবহার করতে হয় তা জানুন।

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

আপনার লেআউট তৈরি করতে ব্যবহৃত বিভিন্ন ভিউ ক্লাসের মধ্যে, আপনি বেশ কিছু পাবলিক কলব্যাক মেথড দেখতে পারেন যা UI ইভেন্টের জন্য বেশ দরকারি বলে মনে হয়। যখন কোনো অবজেক্টে সংশ্লিষ্ট অ্যাকশনটি ঘটে, তখন অ্যান্ড্রয়েড ফ্রেমওয়ার্ক এই মেথডগুলোকে কল করে। উদাহরণস্বরূপ, যখন একটি ভিউ (যেমন একটি বাটন) স্পর্শ করা হয়, তখন সেই অবজেক্টে onTouchEvent() মেথডটি কল করা হয়। তবে, এটি ইন্টারসেপ্ট করার জন্য, আপনাকে অবশ্যই ক্লাসটি এক্সটেন্ড করতে হবে এবং মেথডটি ওভাররাইড করতে হবে। কিন্তু, এই ধরনের ইভেন্ট হ্যান্ডেল করার জন্য প্রতিটি ভিউ অবজেক্ট এক্সটেন্ড করা বাস্তবসম্মত হবে না। এই কারণেই ভিউ ক্লাসে কলব্যাকসহ বেশ কিছু নেস্টেড ইন্টারফেসও থাকে, যা আপনি অনেক সহজে সংজ্ঞায়িত করতে পারেন। এই ইন্টারফেসগুলো, যাদের ইভেন্ট লিসেনার বলা হয়, আপনার UI-এর সাথে ব্যবহারকারীর ইন্টারঅ্যাকশন ক্যাপচার করার চাবিকাঠি।

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

অনুষ্ঠানের শ্রোতারা

ইভেন্ট লিসেনার হলো View ক্লাসের একটি ইন্টারফেস, যাতে একটিমাত্র কলব্যাক মেথড থাকে। যখন UI-এর কোনো আইটেমের সাথে ব্যবহারকারীর ইন্টারঅ্যাকশনের মাধ্যমে লিসেনারটি রেজিস্টার করা View-টি ট্রিগার হয়, তখন অ্যান্ড্রয়েড ফ্রেমওয়ার্ক এই মেথডগুলোকে কল করে।

ইভেন্ট লিসেনার ইন্টারফেসগুলোতে নিম্নলিখিত কলব্যাক মেথডগুলো অন্তর্ভুক্ত রয়েছে:

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);
    ...
}

আপনার Activity-র অংশ হিসেবে 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() - এটি একটি বুলিয়ান মান রিটার্ন করে যা নির্দেশ করে যে আপনি ইভেন্টটি গ্রহণ করেছেন কিনা এবং এটি আর সামনে এগিয়ে নিয়ে যাওয়া উচিত নয়। অর্থাৎ, যদি আপনি ইভেন্টটি হ্যান্ডেল করে থাকেন এবং এটি এখানেই থেমে যায়, তবে true রিটার্ন করুন; আর যদি আপনি এটি হ্যান্ডেল না করে থাকেন এবং/অথবা ইভেন্টটি অন্য কোনো অন-ক্লিক লিসেনারে চলতে থাকে, তবে false রিটার্ন করুন।
  • onKey() - এটি একটি বুলিয়ান মান রিটার্ন করে যা নির্দেশ করে যে আপনি ইভেন্টটি গ্রহণ করেছেন কিনা এবং এটি আর সামনে এগিয়ে নিয়ে যাওয়া উচিত নয়। অর্থাৎ, ইভেন্টটি হ্যান্ডেল করা হয়ে গেলে এবং এখানেই থেমে গেলে এটি true রিটার্ন করে; আর যদি হ্যান্ডেল না করে থাকেন এবং/অথবা ইভেন্টটি অন্য কোনো অন-কী লিসেনারে চলতে থাকে, তাহলে false রিটার্ন করে।
  • onTouch() - এটি একটি বুলিয়ান রিটার্ন করে যা নির্দেশ করে যে আপনার লিসেনার এই ইভেন্টটি গ্রহণ করবে কি না। গুরুত্বপূর্ণ বিষয় হলো, এই ইভেন্টের একাধিক অ্যাকশন থাকতে পারে যা একে অপরের পরে আসে। সুতরাং, ডাউন অ্যাকশন ইভেন্টটি পাওয়ার পর যদি আপনি ফলস (false) রিটার্ন করেন, তাহলে আপনি বোঝাচ্ছেন যে আপনি ইভেন্টটি গ্রহণ করেননি এবং এই ইভেন্টের পরবর্তী অ্যাকশনগুলোতেও আগ্রহী নন। ফলে, ইভেন্টের ভেতরের অন্য কোনো অ্যাকশনের জন্য, যেমন আঙুলের অঙ্গভঙ্গি বা পরবর্তী আপ অ্যাকশন ইভেন্টের জন্য, আপনাকে কল করা হবে না।

মনে রাখবেন যে হার্ডওয়্যার কী ইভেন্টগুলি সর্বদা বর্তমানে ফোকাসে থাকা ভিউতে পাঠানো হয়। এগুলি ভিউ হায়ারার্কির শীর্ষ থেকে শুরু করে নিচের দিকে পাঠানো হয়, যতক্ষণ না সেগুলি উপযুক্ত গন্তব্যে পৌঁছায়। যদি আপনার ভিউ (বা আপনার ভিউ-এর কোনো চাইল্ড) বর্তমানে ফোকাসে থাকে, তাহলে আপনি dispatchKeyEvent() মেথডের মাধ্যমে ইভেন্টটি যেতে দেখতে পাবেন। আপনার ভিউ-এর মাধ্যমে কী ইভেন্টগুলি গ্রহণ করার বিকল্প হিসেবে, আপনি onKeyDown() এবং onKeyUp() ব্যবহার করে আপনার অ্যাক্টিভিটির ভিতরেও সমস্ত ইভেন্ট গ্রহণ করতে পারেন।

এছাড়াও, আপনার অ্যাপ্লিকেশনের জন্য টেক্সট ইনপুট নিয়ে ভাবার সময় মনে রাখবেন যে, অনেক ডিভাইসে শুধুমাত্র সফটওয়্যার ইনপুট মেথড থাকে। এই ধরনের মেথডগুলো যে কী-ভিত্তিক হতেই হবে এমন কোনো বাধ্যবাধকতা নেই; কিছু ক্ষেত্রে ভয়েস ইনপুট, হাতে লেখা ইত্যাদি ব্যবহার করা যেতে পারে। এমনকি যদি কোনো ইনপুট মেথড একটি কীবোর্ডের মতো ইন্টারফেস উপস্থাপন করে, তবুও এটি সাধারণত onKeyDown() ধরনের ইভেন্টগুলোকে ট্রিগার করবে না । আপনার অ্যাপ্লিকেশনটিকে হার্ডওয়্যার কীবোর্ডযুক্ত ডিভাইসের মধ্যে সীমাবদ্ধ রাখতে না চাইলে, এমন কোনো UI তৈরি করা উচিত নয় যা নিয়ন্ত্রণের জন্য নির্দিষ্ট কী চাপার প্রয়োজন হয়। বিশেষ করে, ব্যবহারকারী যখন রিটার্ন কী চাপেন, তখন ইনপুট যাচাই করার জন্য এই মেথডগুলোর উপর নির্ভর করবেন না; এর পরিবর্তে, আপনার অ্যাপ্লিকেশনটি কীভাবে প্রতিক্রিয়া আশা করে তা ইনপুট মেথডকে জানানোর জন্য IME_ACTION_DONE মতো অ্যাকশন ব্যবহার করুন, যাতে এটি তার UI-কে অর্থপূর্ণভাবে পরিবর্তন করতে পারে। একটি সফটওয়্যার ইনপুট মেথড কীভাবে কাজ করা উচিত সে সম্পর্কে অনুমান করা থেকে বিরত থাকুন এবং আপনার অ্যাপ্লিকেশনে আগে থেকেই ফরম্যাট করা টেক্সট সরবরাহ করার জন্য কেবল এর উপর বিশ্বাস রাখুন।

দ্রষ্টব্য: অ্যান্ড্রয়েড প্রথমে ইভেন্ট হ্যান্ডলারগুলোকে কল করে এবং তারপর ক্লাস ডেফিনিশন থেকে উপযুক্ত ডিফল্ট হ্যান্ডলারগুলোকে কল করে। তাই, এই ইভেন্ট লিসেনারগুলো থেকে 'true' রিটার্ন করলে অন্যান্য ইভেন্ট লিসেনারে ইভেন্টের প্রচার বন্ধ হয়ে যাবে এবং ভিউ-এর ডিফল্ট ইভেন্ট হ্যান্ডলারের কলব্যাকও ব্লক হয়ে যাবে। সুতরাং, 'true' রিটার্ন করার সময় নিশ্চিত হয়ে নিন যে আপনি ইভেন্টটি বন্ধ করতে চান।

ইভেন্ট হ্যান্ডলার

আপনি যদি ভিউ থেকে একটি কাস্টম কম্পোনেন্ট তৈরি করেন, তাহলে আপনি ডিফল্ট ইভেন্ট হ্যান্ডলার হিসেবে ব্যবহৃত বেশ কয়েকটি কলব্যাক মেথড সংজ্ঞায়িত করতে পারবেন। কাস্টম ভিউ কম্পোনেন্ট সম্পর্কিত ডকুমেন্টেশনে, আপনি ইভেন্ট হ্যান্ডলিংয়ের জন্য ব্যবহৃত কিছু সাধারণ কলব্যাক সম্পর্কে জানতে পারবেন, যার মধ্যে রয়েছে:

  • onKeyDown(int, KeyEvent) - যখন কোনো নতুন কী ইভেন্ট ঘটে তখন কল করা হয়।
  • onKeyUp(int, KeyEvent) - কী-আপ ইভেন্ট ঘটলে এটি কল করা হয়।
  • onTrackballEvent(MotionEvent) - যখন কোনো ট্র্যাকবলের গতি ইভেন্ট ঘটে তখন এটি কল করা হয়।
  • onTouchEvent(MotionEvent) - টাচ স্ক্রিন মোশন ইভেন্ট ঘটলে এটি কল করা হয়।
  • onFocusChanged(boolean, int, Rect) - যখন ভিউটি ফোকাস পায় বা হারায় তখন এটি কল করা হয়।

আরও কিছু পদ্ধতি আছে যেগুলো সম্পর্কে আপনার সচেতন থাকা উচিত। এগুলো View ক্লাসের অংশ না হলেও, ইভেন্ট পরিচালনার পদ্ধতিকে সরাসরি প্রভাবিত করতে পারে। তাই, একটি লেআউটের ভেতরে আরও জটিল ইভেন্টগুলো পরিচালনা করার সময় এই অন্যান্য পদ্ধতিগুলো বিবেচনা করুন:

টাচ মোড

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

টাচ-সক্ষম ডিভাইসের ক্ষেত্রে, ব্যবহারকারী স্ক্রিনে স্পর্শ করলেই ডিভাইসটি টাচ মোডে প্রবেশ করবে। এই পর্যায় থেকে, শুধুমাত্র সেইসব ভিউ-ই ফোকাসযোগ্য হবে, যেগুলোর জন্য isFocusableInTouchMode() ফাংশনটি true সেট করা আছে, যেমন টেক্সট এডিটিং উইজেট। বাটনের মতো অন্যান্য টাচযোগ্য ভিউ স্পর্শ করলে ফোকাস পাবে না; চাপ দিলে সেগুলো কেবল তাদের অন-ক্লিক লিসেনার চালু করবে।

যখনই কোনো ব্যবহারকারী কোনো ডিরেকশনাল কী চাপেন বা ট্র্যাকবল দিয়ে স্ক্রল করেন, ডিভাইসটি টাচ মোড থেকে বেরিয়ে আসবে এবং ফোকাস নেওয়ার জন্য একটি ভিউ খুঁজে নেবে। এখন, ব্যবহারকারী স্ক্রিনে স্পর্শ না করেই ইউজার ইন্টারফেসের সাথে মিথস্ক্রিয়া পুনরায় শুরু করতে পারেন।

টাচ মোড অবস্থাটি পুরো সিস্টেম জুড়ে (সমস্ত উইন্ডো এবং অ্যাক্টিভিটিতে) বজায় থাকে। বর্তমান অবস্থা জানতে, ডিভাইসটি বর্তমানে টাচ মোডে আছে কিনা তা দেখার জন্য আপনি isInTouchMode() কল করতে পারেন।

ফোকাস পরিচালনা

ফ্রেমওয়ার্কটি ব্যবহারকারীর ইনপুটের প্রতিক্রিয়ায় নিয়মিত ফোকাস পরিবর্তন পরিচালনা করবে। এর মধ্যে রয়েছে ভিউ সরানো বা লুকানো হলে, অথবা নতুন ভিউ উপলব্ধ হলে ফোকাস পরিবর্তন করা। ভিউগুলো isFocusable() মেথডের মাধ্যমে ফোকাস নেওয়ার ইচ্ছা প্রকাশ করে। কোনো ভিউ ফোকাস নিতে পারবে কি না তা পরিবর্তন করতে, setFocusable() কল করুন। টাচ মোডে থাকাকালীন, আপনি isFocusableInTouchMode() ব্যবহার করে কোনো ভিউ ফোকাসের অনুমতি দেবে কি না তা জানতে পারেন। আপনি setFocusableInTouchMode() ব্যবহার করে এটি পরিবর্তন করতে পারেন।

অ্যান্ড্রয়েড ৯ (এপিআই লেভেল ২৮) বা তার উচ্চতর সংস্করণে চালিত ডিভাইসগুলিতে, অ্যাক্টিভিটিগুলি স্বয়ংক্রিয়ভাবে ইনিশিয়াল ফোকাস নির্ধারণ করে না। এর পরিবর্তে, যদি প্রয়োজন হয়, আপনাকে স্পষ্টভাবে ইনিশিয়াল ফোকাসের জন্য অনুরোধ করতে হবে।

ফোকাসের চলাচল একটি অ্যালগরিদমের উপর ভিত্তি করে হয়, যা একটি নির্দিষ্ট দিকে নিকটতম প্রতিবেশীকে খুঁজে বের করে। বিরল ক্ষেত্রে, ডিফল্ট অ্যালগরিদম ডেভেলপারের কাঙ্ক্ষিত আচরণের সাথে নাও মিলতে পারে। এই পরিস্থিতিতে, আপনি লেআউট ফাইলে নিম্নলিখিত 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() ব্যবহার করুন।