যেহেতু এই প্রশ্ন এবং উত্তরগুলির কয়েকটি পাঁচ বছরেরও বেশি পুরানো, তাই আমার সমাধানটি ভাগ করে নেওয়া যাক। এটি @ অয়েনিগুনের উত্তরটির অনুসরণ এবং আধুনিকীকরণ
হালনাগাদ:
এই নিবন্ধের নীচে, আমি একটি অ্যাবস্ট্রাক্ট ফ্র্যাগমেন্ট এক্সটেনশন ব্যবহার করে একটি বিকল্প বাস্তবায়ন যুক্ত করেছি যা ক্রিয়াকলাপের সাথে জড়িত হবে না, যা আরও জটিল কাঠামোগুলি হায়ারার্কিযুক্ত নেস্টেড টুকরো জড়িত যেগুলির জন্য বিভিন্ন ব্যাক আচরণ প্রয়োজন useful
আমাকে এটি বাস্তবায়ন করার প্রয়োজন ছিল কারণ আমি যে কয়েকটি টুকরোগুলি ব্যবহার করি তার কিছু ছোট দৃষ্টিভঙ্গি রয়েছে যা আমি পিছনের বোতামের সাথে খারিজ করতে চাই, যেমন পপআপ হওয়া ছোট ছোট তথ্যের মতামত, ইত্যাদি, তবে যার আচরণের উপর নজর রাখতে হবে তার পক্ষে এটি ভাল টুকরা ভিতরে ফিরে বোতাম।
প্রথমে একটি ইন্টারফেস সংজ্ঞায়িত করুন
public interface Backable {
boolean onBackPressed();
}
এই ইন্টারফেসটি, যা আমি বলি Backable
(নামকরণের কনভেনশনগুলির জন্য আমি স্টিলার), এর একটি একক পদ্ধতি রয়েছে onBackPressed()
যা অবশ্যই একটি boolean
মূল্য ফেরত দেয় । আমাদের একটি বুলিয়ান মান প্রয়োগ করতে হবে কারণ পিছনের বোতাম টিপে পিছনের ইভেন্টটি "শোষণ" করেছে কিনা তা আমাদের জানতে হবে। ফিরে আসার true
অর্থ এর রয়েছে এবং এর পরে আর কোনও পদক্ষেপের দরকার নেই, অন্যথায়, false
ডিফল্ট ব্যাক ক্রিয়াটি এখনও অবশ্যই হওয়া উচিত। এই ইন্টারফেসটি নিজস্ব ফাইল হওয়া উচিত (পছন্দমত পৃথক প্যাকেজের নামে interfaces
)। মনে রাখবেন, আপনার ক্লাসগুলি প্যাকেজগুলিতে পৃথক করা ভাল অনুশীলন।
দ্বিতীয়ত, শীর্ষ টুকরাটি সন্ধান করুন
আমি এমন একটি পদ্ধতি তৈরি করেছি Fragment
যা পিছনের স্ট্যাকের শেষ অবজেক্টটিকে ফেরত দেয় । আমি ট্যাগগুলি ব্যবহার করি ... আপনি যদি আইডি ব্যবহার করেন তবে প্রয়োজনীয় পরিবর্তনগুলি করুন। আমার কাছে এই স্ট্যাটিক পদ্ধতিটি একটি ইউটিলিটি শ্রেণিতে রয়েছে যা নেভিগেশন রাজ্যগুলি ইত্যাদির সাথে সম্পর্কিত ... সংশোধন করার জন্য, আমি আমার নামক একটি ক্লাসে রেখেছি NavUtils
।
public static Fragment getCurrentFragment(Activity activity) {
FragmentManager fragmentManager = activity.getFragmentManager();
if (fragmentManager.getBackStackEntryCount() > 0) {
String lastFragmentName = fragmentManager.getBackStackEntryAt(
fragmentManager.getBackStackEntryCount() - 1).getName();
return fragmentManager.findFragmentByTag(lastFragmentName);
}
return null;
}
নিশ্চিত করুন যে পিছনের স্ট্যাকের গণনা 0 এর চেয়ে বেশি, অন্যথায় ArrayOutOfBoundsException
রানটাইমের সময় নিক্ষেপ করা যেতে পারে। যদি এটি 0 এর চেয়ে বেশি না হয় তবে নালার দিকে ফিরে যান। আমরা পরে একটি শূন্য মান পরীক্ষা করব ...
তৃতীয়, একটি খণ্ডে প্রয়োগ করুন
Backable
ইন্টারফেসটি যে কোনও খণ্ডে প্রয়োগ করুন যেখানে আপনাকে পিছনের বোতামের আচরণটি ওভাররাইড করতে হবে। বাস্তবায়ন পদ্ধতি যুক্ত করুন।
public class SomeFragment extends Fragment implements
FragmentManager.OnBackStackChangedListener, Backable {
...
@Override
public boolean onBackPressed() {
// Logic here...
if (backButtonShouldNotGoBack) {
whateverMethodYouNeed();
return true;
}
return false;
}
}
ইন onBackPressed()
ওভাররাইড যাই হোক না কেন যুক্তিবিজ্ঞান আপনার যা দরকার করা। আপনি যদি পিছনের বোতামটি ব্যাক স্ট্যাকটি পপ না করতে চান (ডিফল্ট আচরণ), সত্য ফিরে আসুন, আপনার পিছনের ইভেন্টটি শোষিত হয়েছে। অন্যথায়, মিথ্যা ফিরে।
শেষ অবধি, আপনার ক্রিয়াকলাপে ...
onBackPressed()
পদ্ধতিটি ওভাররাইড করুন এবং এটিতে এই যুক্তি যুক্ত করুন:
@Override
public void onBackPressed() {
// Get the current fragment using the method from the second step above...
Fragment currentFragment = NavUtils.getCurrentFragment(this);
// Determine whether or not this fragment implements Backable
// Do a null check just to be safe
if (currentFragment != null && currentFragment instanceof Backable) {
if (((Backable) currentFragment).onBackPressed()) {
// If the onBackPressed override in your fragment
// did absorb the back event (returned true), return
return;
} else {
// Otherwise, call the super method for the default behavior
super.onBackPressed();
}
}
// Any other logic needed...
// call super method to be sure the back button does its thing...
super.onBackPressed();
}
আমরা পিছনের স্ট্যাকটিতে বর্তমান টুকরাটি পাই, তারপরে আমরা একটি শূন্য পরীক্ষা করি এবং এটি আমাদের Backable
ইন্টারফেস প্রয়োগ করে কিনা তা নির্ধারণ করি । যদি তা হয় তবে ইভেন্টটি শোষিত হয়েছিল কিনা তা নির্ধারণ করুন। যদি তা হয় তবে আমরা শেষ করেছি onBackPressed()
এবং ফিরে আসতে পারি। অন্যথায়, এটি একটি সাধারণ ব্যাক প্রেস হিসাবে ধরে চিকিত্সা করুন এবং সুপার পদ্ধতিটি কল করুন।
ক্রিয়াকলাপ জড়িত না করার দ্বিতীয় বিকল্প
কখনও কখনও, আপনি কার্যকলাপটি একেবারেই হ্যান্ডেল করতে চান না এবং আপনার এটি খণ্ডের মধ্যে সরাসরি পরিচালনা করতে হবে। তবে কে বলছেন আপনার পিছনে পিপির এপিআই দিয়ে টুকরো থাকতে পারে না ? আপনার খণ্ডকে কেবল নতুন ক্লাসে প্রসারিত করুন।
একটি বিমূর্ত শ্রেণি তৈরি করুন যা খণ্ডকে প্রসারিত করে এবং View.OnKeyListner
ইন্টারফেস প্রয়োগ করে ...
import android.app.Fragment;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
public abstract class BackableFragment extends Fragment implements View.OnKeyListener {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(this);
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackButtonPressed();
return true;
}
}
return false;
}
public abstract void onBackButtonPressed();
}
আপনি দেখতে পাচ্ছেন যে কোনও খণ্ড প্রসারিত BackableFragment
হবে View.OnKeyListener
ইন্টারফেসটি ব্যবহার করে স্বয়ংক্রিয়ভাবে ক্লিকগুলি ক্যাপচার করবে । একটি ব্যাক বোতাম টিপুন সনাক্তকরণের জন্য স্ট্যান্ডার্ড লজিকটি ব্যবহার করে onBackButtonPressed()
বাস্তবায়িত onKey()
পদ্ধতির মধ্যে থেকে কেবল বিমূর্ত পদ্ধতিটি কল করুন । আপনার যদি পিছনের বোতামটি বাদে কী ক্লিকগুলি নিবন্ধভুক্ত করতে হয় তবে আপনার খণ্ডে super
ওভাররাইড করার সময় কেবল পদ্ধতিটি কল করতে ভুলবেন না onKey()
অন্যথায় আপনি বিমূর্তিতে আচরণটি ওভাররাইড করবেন।
ব্যবহারে সহজ, কেবল প্রসারিত এবং প্রয়োগ করুন:
public class FragmentChannels extends BackableFragment {
...
@Override
public void onBackButtonPressed() {
if (doTheThingRequiringBackButtonOverride) {
// do the thing
} else {
getActivity().onBackPressed();
}
}
...
}
যেহেতু onBackButtonPressed()
সুপার ক্লাসের পদ্ধতিটি বিমূর্ত, একবার প্রসারিত করার পরে আপনাকে অবশ্যই প্রয়োগ করতে হবে onBackButtonPressed()
। এটি ফিরে আসে void
কারণ এটি খণ্ড খণ্ডের মধ্যে কেবল একটি ক্রিয়া সম্পাদন করা প্রয়োজন এবং প্রেসের শোষণটিকে পুনরায় ক্রিয়াকলাপে রিলে করার দরকার নেই। নিশ্চিত করুন যে আপনি onBackPressed()
ব্যাক বোতামটি যা করছেন তার জন্য যদি হ্যান্ডলিংয়ের প্রয়োজন না হয় তবে আপনি ক্রিয়াকলাপ পদ্ধতিটি কল করেছেন কিনা তা নিশ্চিত করুন , অন্যথায়, পিছনের বোতামটি অক্ষম হয়ে যাবে ... এবং আপনি এটি চান না!
ক্যাভেটস
যেমন আপনি দেখতে পাচ্ছেন, এটি মূল শ্রোতাটিকে খণ্ডটির মূল দৃশ্যের জন্য সেট করে এবং আমাদের এটি ফোকাস করা দরকার। যদি এই বিভাগটি প্রসারিত আপনার বিভাগে (বা অন্য কোনও ফোকাস-স্টিলিং ভিউ) সম্পাদনা সংক্রান্ত পাঠ্যগুলি থাকে, (বা অন্যান্য অভ্যন্তরীণ টুকরোগুলি বা একই ধরণের মতামত), আপনাকে আলাদাভাবে এটি পরিচালনা করতে হবে। ব্যাক প্রেসে ফোকাস হারাতে এডিটেক্সট প্রসারিত করার জন্য একটি ভাল নিবন্ধ রয়েছে ।
আমি আশা করি যে কেউ এই দরকারী খুঁজে পেয়েছে। শুভ কোডিং।