Fragments में onBackPressed () को कैसे लागू करें?


459

क्या कोई तरीका है जिसमें हम लागू कर सकते हैं onBackPressed() एंड्रॉइड फ्रैगमेंट में उसी तरह से जिस तरह से हम एंड्रॉइड गतिविधि में लागू करते हैं?

जैसा कि फ्रैगमेंट जीवनचक्र नहीं है onBackPressed()। क्या onBackPressed()एंड्रॉइड 3.0 टुकड़ों में सवारी करने के लिए कोई अन्य वैकल्पिक तरीका है ?


13
IMHO, एक टुकड़े को ना तो पता होना चाहिए और ना ही BACK बटन की परवाह करनी चाहिए। एक गतिविधि बैक बटन के बारे में परवाह कर सकती है, हालांकि उन टुकड़ों के साथ जो सामान्य रूप से FragmentManager द्वारा नियंत्रित किए जाते हैं। लेकिन चूंकि टुकड़े को इसके बड़े वातावरण (जैसे कि गतिविधि में कई में से एक है या नहीं) के बारे में नहीं पता है, यह एक टुकड़ा के लिए वास्तव में सुरक्षित नहीं है यह निर्धारित करने की कोशिश करने के लिए कि क्या उचित बैक कार्यक्षमता है।
कॉमंसवेयर

61
कैसे के बारे में जब सभी टुकड़े एक WebView प्रदर्शित करने के लिए करता है, और आप चाहते हैं कि जब पिछला बटन दबाया जाए तो WebView पिछले पृष्ठ पर "वापस जाएं"?
१:१२ बजे ०११

माइकल हर्बिग जवाब मेरे लिए एकदम सही था। लेकिन उन लोगों के लिए जो कठबोली का उपयोग करते हैं getSupportFragmentManager ()। इसके बजाय getFragmentManager () का उपयोग करें।
दंतैल

दिमित्री ज़ैतसेव का जवाब [इसी तरह के सवाल] [1] पर ठीक काम करता है। [1]: stackoverflow.com/a/13450668/1372866
आश्रिकोव २१'१३

6
जवाब देने के लिए आप कुछ भी कर सकते हैं जैसे webview.setOnKeyListener (नया OnKeyListener () {@Override सार्वजनिक बूलियन onKey (देखें v, int कीकोड, KeyEvent घटना) {if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBackBack {webview.goBack (); सही लौटें?} झूठे लौटें;}});
ओमिड अमीनावा २

जवाबों:


307

मैंने इस तरह onBackPressedसे गतिविधि में ओवरराइड किया। सभी FragmentTransactionकर रहे हैं addToBackStackके लिए प्रतिबद्ध से पहले:

@Override
public void onBackPressed() {

    int count = getSupportFragmentManager().getBackStackEntryCount();

    if (count == 0) {
        super.onBackPressed();
        //additional code
    } else {
        getSupportFragmentManager().popBackStack();
    }

}


4
गिनती == 1 सिंगल बैक बटन प्रेस पर पहले टुकड़े को बंद करने की अनुमति देगा। लेकिन अन्यथा सबसे अच्छा समाधान
कुनालक्सीगैग

2
यदि आप समर्थन v7 लाइब्रेरी का उपयोग कर रहे हैं और आपकी गतिविधि FragmentActivity (या AppCompatActivity जैसे उप-वर्ग) से फैली हुई है , तो यह डिफ़ॉल्ट रूप से होगा। FragmentActivity # onBackPressed
जिओ

3
लेकिन आप इस कोड में खंड के वर्ग से चर, वर्गों और कार्यों का उपयोग नहीं कर सकते
user25

2
@ यदि आप समर्थन v4 टुकड़े का उपयोग कर रहे हैं, तो सुनिश्चित करें कि आप getSupportFragmentManager () का उपयोग कर रहे हैं। getBackStackEntryCount ();
वीर .3383

151

मेरी राय में सबसे अच्छा समाधान है:

जावा समाधान

सरल इंटरफ़ेस बनाएँ:

public interface IOnBackPressed {
    /**
     * If you return true the back press will not be taken into account, otherwise the activity will act naturally
     * @return true if your processing has priority if not false
     */
    boolean onBackPressed();
}

और आपकी गतिविधि में

public class MyActivity extends Activity {
    @Override public void onBackPressed() {
    Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
       if (!(fragment instanceof IOnBackPressed) || !((IOnBackPressed) fragment).onBackPressed()) {
          super.onBackPressed();
       }
    } ...
}

अंत में आपके टुकड़े में:

public class MyFragment extends Fragment implements IOnBackPressed{
   @Override
   public boolean onBackPressed() {
       if (myCondition) {
            //action not popBackStack
            return true; 
        } else {
            return false;
        }
    }
}

कोटलिन समाधान

1 - इंटरफ़ेस बनाएँ

interface IOnBackPressed {
    fun onBackPressed(): Boolean
}

2 - अपनी गतिविधि तैयार करें

class MyActivity : AppCompatActivity() {
    override fun onBackPressed() {
        val fragment =
            this.supportFragmentManager.findFragmentById(R.id.main_container)
        (fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let {
            super.onBackPressed()
        }
    }
}

3 - अपने लक्ष्य को लागू करें

class MyFragment : Fragment(), IOnBackPressed {
    override fun onBackPressed(): Boolean {
        return if (myCondition) {
            //action not popBackStack
            true
        } else {
            false
        }
    }
}

1
क्या है R.id.main_container? यह FragmentPager के लिए आईडी है?
नाथन एफ

1
कोटलिन समाधान में @MaximeJallu, सुरक्षित कॉल ( .?) और गैर- !!नलियों ( ) को लागू करने से NPEs हो सकता है - कलाकार हमेशा सुरक्षित नहीं होता है। मैं नहीं बल्कि if ((fragment as? IOnBackPressed)?.onBackPressed()?.not() == true) { ... }अधिक kotliney लिखना चाहता हूँ(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let { ... }
Antek

1
@Antek हैलो, आपकी वापसी के लिए धन्यवाद, आप अपना सुधार करने के लिए पोस्ट को संपादित कर सकते थे। समग्र समाधान को गंभीरता से न लें।
मैक्सिम जल्लू

4
यह नहीं होना चाहिए .onBackPressed()?.takeIf { !it }?.let{...}? .not()बस प्रतिलोम लौटाता है।
डेविड मिगुएल

1
val fragment = this.supportFragmentManager.findFragmentById(R.id.flContainer) as? NavHostFragment val currentFragment = fragment?.childFragmentManager?.fragments?.get(0) as? IOnBackPressed currentFragment?.onBackPressed()?.takeIf { !it }?.let{ super.onBackPressed() }यह उन लोगों के लिए है जो कोटलिन और नेवीगेशन कंट्रोलर
Pavle Pavlov

97

@HaMMeRed जवाब के अनुसार यहाँ छद्म कोड है कि यह कैसे काम करता है। आओ हम कहते हैं कि आपकी मुख्य गतिविधि को कहा जाता है BaseActivityजिसमें बाल टुकड़े होते हैं (जैसे स्लाइडिंगमेनू के उदाहरण में)। यहाँ कदम हैं:

सबसे पहले हमें इंटरफेस और क्लास बनाने की जरूरत है जो इसके इंटरफेस को सामान्य तरीके से लागू करता है

  1. क्लास इंटरफ़ेस बनाएँ OnBackPressedListener

    public interface OnBackPressedListener {
        public void doBack();
    }
  2. कक्षा बनाएँ जो कौशल को लागू करता है OnBackPressedListener

    public class BaseBackPressedListener implements OnBackPressedListener {
        private final FragmentActivity activity;
    
        public BaseBackPressedListener(FragmentActivity activity) {
            this.activity = activity;
        }
    
        @Override
        public void doBack() {
            activity.getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
        }
    }
  3. अब से, हम अपने कोड BaseActivityऔर उसके अंशों पर काम करेंगे

  4. अपनी कक्षा के शीर्ष पर निजी श्रोता बनाएँ BaseActivity

    protected OnBackPressedListener onBackPressedListener;
  5. में श्रोता सेट करने के लिए विधि बनाएँ BaseActivity

    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }
  6. ओवरराइड में onBackPressedऐसा कुछ लागू करें

    @Override
    public void onBackPressed() {
        if (onBackPressedListener != null)
            onBackPressedListener.doBack();
        else
            super.onBackPressed();
  7. आपके टुकड़े में onCreateViewआपको हमारे श्रोता को जोड़ना चाहिए

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        activity = getActivity();
    
        ((BaseActivity)activity).setOnBackPressedListener(new BaseBackPressedListener(activity));
    
        View view = ... ;
    //stuff with view
    
        return view;
    }

वोइला, अब जब आप खंड में वापस क्लिक करते हैं तो आपको अपने कस्टम को बैक विधि पर पकड़ना चाहिए।


यदि एक से अधिक टुकड़े एक श्रोता हैं, तो आप कैसे निर्धारित करते हैं onBackPressed(), किस बैक बटन को दबाने पर किस टुकड़े को प्रदर्शित किया जा रहा था?
अल लेलोपाथ

2
आप नए बेसबेकपार्टलिस्ट की बजाय क्लिक श्रोता को कस्टमाइज़ कर सकते हैं और खुद को बिहेवियर सेट करने के लिए अनाम कह सकते हैं, कुछ इस तरह से:((BaseActivity)activity).setOnBackPressedListener(new OnBackpressedListener(){ public void doBack() { //...your stuff here }});
deadfish

धन्यवाद, मैंने इस पर अपनी स्थिति बदल दी है, हालांकि मैं अब स्थानीय प्रसारण संदेशों के साथ डिकोडिंग की सलाह दूंगा। मुझे लगता है कि यह उच्च गुणवत्ता वाले घटकों का उत्पादन करेगा जो अत्यधिक डिकौप्ड हैं।
HaMMeReD


यह मेरे लिए पूरी तरह से काम करता है, मैं गतिविधि को फिर से शुरू करता हूं
रैपहेलब्रग

86

इसने मेरे लिए काम किया: https://stackoverflow.com/a/27145007/3934111

@Override
public void onResume() {
    super.onResume();

    if(getView() == null){
        return;
    }

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
                // handle back button's click listener
                return true;
            }
            return false;
        }
    });
}

2
निर्दोष रूप से काम किया! लेकिन फिर आपको एक और IF कंडीशन शायद लिखकर डिफ़ॉल्ट एक्शन को भी हैंडल करना होगा। चूंकि, यदि मैं इसका विस्तार किया गया था, तो मैं अपनी स्लाइडअपपनल को कम कर रहा था। इसलिए, मुझे पहले एक चेक को चिह्नित करना था अगर (पैनल ऊपर है) तो .....
sud007

18
इस समाधान के साथ समस्या यह है कि getView () केवल मुख्य दृश्य देता है (और सबव्यू नहीं, यदि वे फोकस प्राप्त करते हैं)। इसलिए यदि आपके पास एक EditText है और कुछ टेक्स्ट टाइप करते हैं, तो कीबोर्ड को छिपाने के लिए एक बार "बैक" दबाएं, "बैक" पर दूसरा प्रेस "EditText" (स्वयं एक दृश्य) से शुरू किया गया है और यह विधि "पकड़" नहीं लगती है बैक "बटन प्रेस (तब से यह केवल मुख्य दृश्य के लिए पकड़ रहा है)। जैसा कि मैंने इसे समझा है, आप अपने "EditText" और साथ ही किसी भी अन्य दृश्य पर मुख्य घटनाओं को पकड़ सकते हैं, लेकिन यदि आपके पास "जटिल" रूप है, तो यह उतना साफ और बनाए रखने योग्य नहीं है जितना यह हो सकता है।
पेलपोथ्रोनिक जूल

यह दुःस्वप्न के लिए एक महान सरल उपाय है जो टुकड़े हैं। यदि आपके पास एक 'जटिल' संपादन प्रपत्र है, तो आपको संभवतः अपनी परियोजना को हटा देना चाहिए और शुरू करना चाहिए। जब आप मानक व्यवहार का उपयोग करना चाहते हैं तो झूठी लौटें। जब आप बैक प्रेस को इंटरसेप्ट करते हैं और उसके साथ कुछ किया है, तो वापस लौटें
behelit

65

यदि आप उस प्रकार की कार्यक्षमता चाहते थे, तो आपको इसे अपनी गतिविधि में ओवरराइड करना होगा, और फिर एक जोड़ना होगा YourBackPressed अपने सभी टुकड़ों में इंटरफ़ेस , जिसे आप प्रासंगिक टुकड़े पर कॉल करते हैं जब भी बैक बटन दबाया जाता है।

संपादित करें: मैं अपना पिछला उत्तर जोड़ना चाहूंगा।

अगर मैं आज ऐसा करता, तो मैं एक प्रसारण का उपयोग करता, या संभवत: एक आदेशित प्रसारण का उपयोग करता, अगर मुझे उम्मीद थी कि अन्य पैनल मास्टर / मुख्य सामग्री पैनल से एकतरफा अपडेट करेंगे।

LocalBroadcastManagerसपोर्ट लाइब्रेरी में इससे मदद मिल सकती है, और आप सिर्फ प्रसारण में onBackPressedऔर अपने अंशों में सदस्यता लें जो देखभाल करते हैं। मुझे लगता है कि मैसेजिंग एक अधिक डिकम्पोज्ड कार्यान्वयन है और यह बेहतर होगा, इसलिए यह अब मेरी आधिकारिक कार्यान्वयन अनुशंसा होगी। बस Intentअपने संदेश के लिए फ़िल्टर के रूप में कार्रवाई का उपयोग करें । अपने नए बनाए गए ACTION_BACK_PRESSED, इसे अपनी गतिविधि से भेजें और संबंधित टुकड़ों में इसके बारे में सुनें।


4
बहुत सुंदर विचार! कुछ अतिरिक्त विचार: + यह महत्वपूर्ण है कि इस तर्क को गतिविधि> अंशों (दूसरे तरीके से नहीं) से प्रसारित प्रसारण के साथ महसूस किया जाए। OnBackPressed केवल एक्टिविटी लेवल पर उपलब्ध है, इसलिए वहां इवेंट को फँसा कर सभी "सुनना" अंशों को प्रसारित करना यहाँ महत्वपूर्ण है। एक EventBus का उपयोग करना (स्क्वायर के ओटो की तरह) इस तुच्छ जैसे मामले के लिए कार्यान्वयन बनाता है!
कौशिक गोपाल

2
मैंने स्क्वायर के EventBus का अभी तक उपयोग नहीं किया है, लेकिन मैं भविष्य के उत्पादों में रहूंगा। मुझे लगता है कि यह एक बेहतर शुद्ध-जावा समाधान है, और यदि आप एंड्रॉइड को अपने आर्किटेक्चर के अनुभागों से बाहर निकाल सकते हैं, तो सभी बेहतर।
HaMMeReD

आप घटना को संभालने के लिए केवल शीर्ष टुकड़े कैसे करते हैं? उदाहरण के लिए, आप वर्तमान में दिख रहे टुकड़े को नष्ट करना चाहेंगे
यूजीन

यदि आप इसका उपयोग कर रहे हैं तो ब्रॉडकास्ट रिसीवर को जीवन चक्र के लिए बाध्य होना चाहिए, इसलिए जब यह दिखाई न दे तो यह घटना को प्राप्त नहीं करना चाहिए।
HaMMeReD

यह भी ध्यान दें कि LocalBroadcastManagerप्रसारण का आदेश नहीं दिया जा सकता है
जिओ

46

इनमें से कोई भी लागू करना आसान नहीं है और न ही यह एक इष्टतम तरीके से कार्य करेगा।

टुकड़े में एक विधि कॉल ऑनडेट है जो काम करेगा।

@Override
    public void onDetach() {
        super.onDetach();
        PUT YOUR CODE HERE
    }

यह काम करेगा।


20
लेकिन यहाँ मुद्दा यह है कि आपको यह नहीं पता है कि बैक प्रेस के कारण टुकड़ा अलग हो गया था या किसी अन्य कार्रवाई के कारण, जिसके कारण उपयोगकर्ता कुछ अन्य गतिविधि या टुकड़े में चला गया।
सनी

7
onDetach () उस समय कहा जाता है जब टुकड़ा अब उसकी गतिविधि से जुड़ा नहीं होता है। यह onDestroy () के बाद कहा जाता है। हालाँकि आपको यह कोड तब मिलेगा जब आप बैक बटन दबाएंगे जब आप खंड से टुकड़े में बदलते हैं तो आपको यह कोड भी मिलेगा। आप इस काम को करने के लिए कुछ निफ्टी कर सकते हैं ...
apmartin1991

एक DialogFragment के लिए ठीक काम करता है।
कूलमाइंड

2
जोड़ने के लिए मत भूलना isRemoving()में वर्णित के रूप stackoverflow.com/a/27103891/2914140
CoolMind

1
ये गलत है। इसे कई कारणों से कहा जा सकता है
बाली

39

यदि आप उपयोग कर रहे हैं androidx.appcompat:appcompat:1.1.0या ऊपर तो आप OnBackPressedCallbackअपने टुकड़े में निम्नानुसार जोड़ सकते हैं

requireActivity()
    .onBackPressedDispatcher
    .addCallback(this, object : OnBackPressedCallback(true) {
        override fun handleOnBackPressed() {
            Log.d(TAG, "Fragment back pressed invoked")
            // Do custom work here    

            // if you want onBackPressed() to be called as normal afterwards
            if (isEnabled) {
                isEnabled = false
                requireActivity().onBackPressed()
            }
        }
    }
)

Https://developer.android.com/guide/navigation/navigation-custom-back देखें


यदि आप उपयोग कर रहे हैं androidx-core-ktx, तो आप उपयोग कर सकते हैंrequireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) { /* code to be executed when back is pressed */ }
अधिकतम

यह ध्यान रखना महत्वपूर्ण है कि LifecycleOwnerपरम को इस उदाहरण में जोड़ा जाना चाहिए। इसके बिना, बाद में शुरू किए गए किसी भी टुकड़े को कॉल करेगा handleBackPressed()यदि बैक बटन दबाया गया है।
एरिक बी।

क्या यह तरीका नेविगेशन लाइब्रेरी के साथ होना चाहिए?
साधना

25

addToBackStackनीचे दिए गए अंशों के बीच परिवर्तन करते समय बस जोड़ें :

fragmentManager.beginTransaction().replace(R.id.content_frame,fragment).addToBackStack("tag").commit();

यदि आप लिखते हैं addToBackStack(null), तो यह इसे अपने आप संभाल लेगा, लेकिन यदि आप एक टैग देते हैं, तो आपको इसे मैन्युअल रूप से संभालना चाहिए।


क्या कुछ और है जिसे जोड़ने की जरूरत है या AddToBackStack विधि को जोड़ना पर्याप्त है?
श्रीचरण देसबत्तुला

1
यदि आप सिर्फ यह कहते हैं कि यह काम करना चाहिए, अगर यह अभी भी काम नहीं कर रहा है तो आपके कोड में कुछ होना चाहिए। कृपया @SreecharanDesabattula
रुडी

@ रुडी आप बता सकते हैं stackoverflow.com/questions/32132623/…
आदित्य व्यास-लखन

20

चूँकि यह प्रश्न और उत्तर में से कुछ पाँच साल से अधिक पुराने हैं, मुझे अपना समाधान साझा करने दें। यह @oyenigun से उत्तर के लिए एक अनुवर्ती और आधुनिकीकरण है

अपडेट करें: इस लेख के निचले भाग में, मैंने एक सार फ्रेगमेंट एक्सटेंशन का उपयोग करते हुए एक वैकल्पिक कार्यान्वयन जोड़ा है जो गतिविधि को बिल्कुल भी शामिल नहीं करेगा, जो किसी भी अधिक जटिल टुकड़े वाले पदानुक्रम के साथ उपयोगी होगा जिसमें नेस्टेड टुकड़े शामिल होते हैं जिन्हें अलग-अलग व्यवहार की आवश्यकता होती है।

मुझे इसे लागू करने की आवश्यकता थी क्योंकि मेरे द्वारा उपयोग किए जाने वाले कुछ अंशों में छोटे दृश्य होते हैं, जिन्हें मैं बैक बटन के साथ खारिज करना चाहता हूं, जैसे कि छोटे जानकारी वाले दृश्य जो पॉप अप करते हैं, आदि, लेकिन यह उन लोगों के लिए अच्छा है जिन्हें व्यवहार को ओवरराइड करने की आवश्यकता है टुकड़े के अंदर वापस बटन।

सबसे पहले, एक इंटरफ़ेस परिभाषित करें

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()विधि को कॉल करते हैं यदि आप बैक बटन के साथ जो कुछ भी कर रहे हैं उसे संभालने की आवश्यकता नहीं है, अन्यथा, बैक बटन अक्षम हो जाएगा ... और आप ऐसा नहीं चाहते हैं!

कैविट्स जैसा कि आप देख सकते हैं, यह प्रमुख श्रोता को खंड के मूल दृश्य पर सेट करता है, और हमें इसे ध्यान केंद्रित करने की आवश्यकता होगी। यदि आपके खंड में शामिल ग्रंथों (या किसी अन्य फ़ोकस-चोरी दृश्य) को शामिल किया गया है जो इस वर्ग को बढ़ाता है, (या अन्य आंतरिक टुकड़े या विचार जो समान हैं), आपको अलग से संभालना होगा। बैक प्रेस पर फ़ोकस खोने के लिए एक EditText का विस्तार करने पर एक अच्छा लेख है ।

मुझे आशा है कि किसी को यह उपयोगी लगता है। खुश कोडिंग।


धन्यवाद, यह एक अच्छा समाधान है। क्या आप कह सकते हैं, आप super.onBackPressed();दो बार क्यों कहते हैं ?
कूलमाइंड

इसे केवल अशक्त स्थिति के बारे में प्रति बार एक बार बुलाया जाता है currentFragment। यदि टुकड़ा अशक्त नहीं है और टुकड़ा Backableइंटरफ़ेस को लागू करता है, तो कोई कार्रवाई नहीं की जाती है। यदि टुकड़ा अशक्त नहीं है और यह लागू नहीं होता है Backable, तो हम सुपर विधि कहते हैं। यदि टुकड़ा अशक्त है, तो यह अंतिम सुपर कॉल को छोड़ देता है।
mwieczorek

क्षमा करें, मुझे समझ नहीं आया। मामले में जब एक currentFragmentशून्य नहीं है और बैकएबल का एक उदाहरण है और इसे अलग किया जाता है (हमने backबटन दबाया और टुकड़े को बंद कर दिया) पहली घटना super.onBackPressed();को बुलाया जाता है, फिर दूसरा।
कूलमाइंड

उत्कृष्ट समाधान
डेविड टोलेडो

शायद "क्लोजेबल" "बैकबल" की तुलना में थोड़ा बेहतर है
पुमनाओ

15

समाधान सरल है:

1) यदि आपके पास एक आधार खंड वर्ग है जो सभी टुकड़े विस्तारित होते हैं, तो इस कोड को इसे कक्षा में जोड़ें, अन्यथा ऐसा आधार खंड वर्ग बनाएं

 /* 
 * called when on back pressed to the current fragment that is returned
 */
 public void onBackPressed()
 {
    // add code in super class when override
 }

2) आपके गतिविधि वर्ग में, ओवरब्रैकपाइड को ओवरराइड करें निम्नानुसार है:

private BaseFragment _currentFragment;

@Override
public void onBackPressed()
{
      super.onBackPressed();
     _currentFragment.onBackPressed();
}

3) अपने फ्रैगमेंट वर्ग में, अपना इच्छित कोड जोड़ें:

 @Override
 public void onBackPressed()
 {
    setUpTitle();
 }


9

onBackPressed() फ्रैगमेंट को गतिविधि से अलग किया जाना चाहिए।

@Sterling Diaz जवाब के अनुसार मुझे लगता है कि वह सही है। लेकिन कुछ स्थिति गलत होगी। (उदा। रोटेट स्क्रीन)

इसलिए, मुझे लगता है कि हम isRemoving()लक्ष्य हासिल करने के बारे में पता लगा सकते हैं ।

आप इसे onDetach()या पर लिख सकते हैं onDestroyView()। यह कार्य है।

@Override
public void onDetach() {
    super.onDetach();
    if(isRemoving()){
        // onBackPressed()
    }
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    if(isRemoving()){
        // onBackPressed()
    }
}

8

वैसे मैंने इसे इस तरह किया है, और यह मेरे लिए काम करता है

सरल इंटरफ़ेस

FragmentOnBackClickInterface.java

public interface FragmentOnBackClickInterface {
    void onClick();
}

उदाहरण कार्यान्वयन

MyFragment.java

public class MyFragment extends Fragment implements FragmentOnBackClickInterface {

// other stuff

public void onClick() {
       // what you want to call onBackPressed?
}

फिर बस गतिविधि में onBackPressed को ओवरराइड करें

    @Override
public void onBackPressed() {
    int count = getSupportFragmentManager().getBackStackEntryCount();
    List<Fragment> frags = getSupportFragmentManager().getFragments();
    Fragment lastFrag = getLastNotNull(frags);
    //nothing else in back stack || nothing in back stack is instance of our interface
    if (count == 0 || !(lastFrag instanceof FragmentOnBackClickInterface)) {
        super.onBackPressed();
    } else {
        ((FragmentOnBackClickInterface) lastFrag).onClick();
    }
}

private Fragment getLastNotNull(List<Fragment> list){
    for (int i= list.size()-1;i>=0;i--){
        Fragment frag = list.get(i);
        if (frag != null){
            return frag;
        }
    }
    return null;
}

काम नहीं कर रहा ! super.onbackpressed () हमेशा कहा जाता है :(
अनिमेश मंगला

इस घटना को इनर फ्रेगमेंट कैसे पास करें। मेरे पास गतिविधि में ViewPager है और ViewPager के पास टुकड़े हैं, अब उन सभी Fragment में बच्चे के टुकड़े हैं। उस बच्चे के टुकड़ों को वापस बटन घटना कैसे पारित करें।
किशन वाघेला

@ किशनवाघेला ने तब से Android को नहीं छुआ था लेकिन मुझे एक विचार है। अपना उत्तर अपडेट करने के लिए मुझे 24 वाँ समय दें।
बलोएज

ठीक है कोई बात नहीं, एक विकल्प यह है कि मुझे माता-पिता के टुकड़े से प्रत्येक बच्चे के टुकड़े को श्रोता घटना को पारित करने की आवश्यकता है। लेकिन यह एक आदर्श तरीका नहीं है क्योंकि मुझे हर टुकड़े के लिए ऐसा करने की आवश्यकता है।
किशन वाघेला

@ किशनवाघेला मैं गतिविधि में प्रबंधक के बारे में सोच रहा था। आप उस इंटरफ़ेस से टुकड़े जोड़ / हटा सकते हैं। लेकिन इस दृष्टिकोण के साथ आपको प्रत्येक खंड में प्रबंधक को लागू करना होगा जिसमें सबफ्रैगमेंट हैं। तो शायद बेहतर समाधान प्रबंधक को सिंगलटन बना देगा। फिर आपको इस प्रबंधक के अंशों / वस्तुओं को जोड़ना और निकालना होगा और 'onBackPressed' को आप 'onBackPressed' विधि कहेंगे। वह विधि प्रबंधक में जोड़े गए प्रत्येक ऑब्जेक्ट में विधि को 'ऑनक्लिक' कहेगी। क्या वह कमोबेश आपके लिए स्पष्ट है?
बलोएज

8

आपको अपनी परियोजना में नीचे की तरह इंटरफ़ेस जोड़ना चाहिए;

public interface OnBackPressed {

     void onBackPressed();
}

और फिर, आपको अपने टुकड़े पर इस इंटरफ़ेस को लागू करना चाहिए;

public class SampleFragment extends Fragment implements OnBackPressed {

    @Override
    public void onBackPressed() {
        //on Back Pressed
    }

}

और आप अपनी गतिविधियों के तहत इस onBackPressed घटना को ट्रिगर कर सकते हैं onBackPressed घटना नीचे की तरह;

public class MainActivity extends AppCompatActivity {
       @Override
        public void onBackPressed() {
                Fragment currentFragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
                if (currentFragment instanceof OnBackPressed) {  
                    ((OnBackPressed) currentFragment).onBackPressed();
                }
                super.onBackPressed();
        }
}

यह एगूड विधि है, लेकिन सावधान रहें, getActivity().onBackPressed();इसे कॉल न करें क्योंकि यह अपवाद को आमंत्रित करेगा: "java.lang.StackOverflowError: stack size 8MB"।
कूलमाइंड

8

यह सिर्फ एक छोटा कोड है जो इस चाल को करेगा:

 getActivity().onBackPressed();

आशा है कि यह किसी की मदद करता है :)


4
उन्होंने व्यवहार को ओवरराइड करने के लिए कहा, न कि केवल गतिविधि पद्धति को लागू करने के लिए।
mwieczorek

2
मैंने इसे ध्यान से पढ़ा, धन्यवाद। जब आपका समाधान ओवरराइड करने का तरीका पूछा जाता है, तो आपका समाधान केवल गतिविधि पर वापस जाने के तरीके पर निर्भर करता है।
mwieczorek

7

यदि आप EventBus का उपयोग करते हैं, तो यह संभवतः अधिक सरल समाधान है:

आपके टुकड़े में:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    EventBus.getDefault().register(this);
}

@Override
public void onDetach() {
    super.onDetach();
    EventBus.getDefault().unregister(this);
}


// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
    getSupportFragmentManager().popBackStack();
}

और अपने गतिविधि वर्ग में आप परिभाषित कर सकते हैं:

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

// This method will be called when a MessageEvent is posted
public void onEvent(BackPressedMessage type){
    super.onBackPressed();
}

@Override
public void onBackPressed() {
    EventBus.getDefault().post(new BackPressedMessage(true));
}

BackPressedMessage.java केवल एक POJO ऑब्जेक्ट है

यह सुपर क्लीन है और कोई इंटरफ़ेस / कार्यान्वयन परेशानी नहीं है।


7

यह मेरा समाधान है:

में MyActivity.java:

public interface OnBackClickListener {
        boolean onBackClick();
    }

    private OnBackClickListener onBackClickListener;

public void setOnBackClickListener(OnBackClickListener onBackClickListener) {
        this.onBackClickListener = onBackClickListener;
    }

@Override
    public void onBackPressed() {
        if (onBackClickListener != null && onBackClickListener.onBackClick()) {
            return;
        }
        super.onBackPressed();
    }

और खुशबू में:

((MyActivity) getActivity()).setOnBackClickListener(new MyActivity.OnBackClickListener() {
    @Override
    public boolean onBackClick() {
        if (condition) {
            return false;
        }

        // some codes

        return true;
    }
});

5

नेविगेशन घटक का उपयोग करके आप इसे इस तरह कर सकते हैं :

जावा

public class MyFragment extends Fragment {

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // This callback will only be called when MyFragment is at least Started.
    OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
        @Override
        public void handleOnBackPressed() {
            // Handle the back button event
        }
    });
    requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

    // The callback can be enabled or disabled here or in handleOnBackPressed()
}
...
}

Kotlin

class MyFragment : Fragment() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // This callback will only be called when MyFragment is at least Started.
    val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
        // Handle the back button event
    }

    // The callback can be enabled or disabled here or in the lambda
}
...
}

4

OnDestroyView () का उपयोग करने के बारे में कैसे?

@Override
public void onDestroyView() {
    super.onDestroyView();
}

5
वास्तविक टुकड़े से दूसरे टुकड़े में जाने के बारे में, आपकी पद्धति का उपयोग करने से क्या होगा? :)
चोलत्स्की

सबसे बेकार जवाब। यह लेखन i = iया के रूप में ही है if (1 < 0) {}
कूलमाइंड

4
@Override
public void onResume() {
    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button
                replaceFragmentToBackStack(getActivity(), WelcomeFragment.newInstance(bundle), tags);

                return true;
            }

            return false;
        }
    });
}

केवल अगर टुकड़ों में फ़ोकस करने योग्य दृश्य नहीं होता है (जैसे कि टेक्स्ट संपादित करें), तो टुकड़ों को वापस बटन संभालना चाहिए जैसा कि यह उत्तर करता है। अन्यथा, पहली गतिविधि के लिखे जाने के अनुसार, गतिविधि को OnBackPress () द्वारा कराएं; चूंकि फ़ोकस करने योग्य दृश्य टुकड़े के फ़ोकस को चुरा लेगा। हालाँकि, हम स्पष्ट फ़ोकस () पद्धति द्वारा सभी फ़ोकस करने योग्य विचारों पर फ़ोकस करके और फ़्रेग्मेंट पर फ़ोकस करके फ़ोकस को पुनः प्राप्त कर सकते हैं।
गुयेन टैन डाट

4
public class MyActivity extends Activity {

    protected OnBackPressedListener onBackPressedListener;

    public interface OnBackPressedListener {
        void doBack();
    }

    public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }

    @Override
    public void onBackPressed() {
        if (onBackPressedListener != null)
            onBackPressedListener.doBack();
        else
            super.onBackPressed();
    } 

    @Override
    protected void onDestroy() {
        onBackPressedListener = null;
        super.onDestroy();
    }
}

अपने टुकड़े में निम्नलिखित जोड़ें, न मुख्यता के इंटरफ़ेस को लागू करना न भूलें।

public class MyFragment extends Framgent implements MyActivity.OnBackPressedListener {
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
         ((MyActivity) getActivity()).setOnBackPressedListener(this);
    }

@Override
public void doBack() {
    //BackPressed in activity will call this;
}

}

4

मेरे समाधान (कोटलिन) में;

मैं पर एक पैरामीटर के रूप onBackAlternative समारोह का उपयोग कर रहा BaseActivity

BaseActivity

abstract class BaseActivity {

    var onBackPressAlternative: (() -> Unit)? = null

    override fun onBackPressed() {
        if (onBackPressAlternative != null) {
            onBackPressAlternative!!()
        } else {
            super.onBackPressed()
        }
    }
}

मैं सेट के लिए एक समारोह है onBackPressAlternative पर BaseFragment

BaseFragment

abstract class BaseFragment {

     override fun onStart() {
        super.onStart()
        ...
        setOnBackPressed(null) // Add this
     }

      //Method must be declared as open, for overriding in child class
     open fun setOnBackPressed(onBackAlternative: (() -> Unit)?) {
         (activity as BaseActivity<*, *>).onBackPressAlternative = onBackAlternative
     }
}

तब मेरे onBackPressAlternative टुकड़ों पर उपयोग करने के लिए तैयार है।

उप-टुकड़े

override fun setOnBackPressed(onBackAlternative: (() -> Unit)?) {
    (activity as BaseActivity<*, *>).onBackPressAlternative = {
        // TODO Your own custom onback function 
    }
}

3

Ft.addToBackStack () विधि को लागू न करें ताकि जब आपने बैक बटन दबाया तो आपकी गतिविधि समाप्त हो जाएगी।

proAddAccount = new ProfileAddAccount();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, proAddAccount);
//fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();


3

बस इन चरणों का पालन करें:

हमेशा एक टुकड़ा जोड़ते समय,

fragmentTransaction.add(R.id.fragment_container, detail_fragment, "Fragment_tag").addToBackStack(null).commit();

फिर मुख्य गतिविधि में, ओवरराइड करें onBackPressed()

if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
    getSupportFragmentManager().popBackStack();
} else {
    finish();
}

अपने ऐप में बैक बटन को संभालने के लिए,

Fragment f = getActivity().getSupportFragmentManager().findFragmentByTag("Fragment_tag");
if (f instanceof FragmentName) {
    if (f != null) 
        getActivity().getSupportFragmentManager().beginTransaction().remove(f).commit()               
}

बस!


3

जब हम FragmentActivity या AppCompatitctivity का उपयोग करते हैं, तो गतिविधि जीवन चक्र में, हमेशा Android बैक बटन FragmentManager लेनदेन से संबंधित होता है।

बैकस्टैक को संभालने के लिए हमें इसके बैकस्टैक काउंट को संभालने या कुछ भी टैग करने की आवश्यकता नहीं है, लेकिन हमें एक टुकड़े को जोड़ने या बदलने के दौरान ध्यान केंद्रित रखना चाहिए। कृपया बैक बटन मामलों को संभालने के लिए निम्नलिखित स्निपेट खोजें,

    public void replaceFragment(Fragment fragment) {

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        if (!(fragment instanceof HomeFragment)) {
            transaction.addToBackStack(null);
        }
        transaction.replace(R.id.activity_menu_fragment_container, fragment).commit();
    }

यहाँ, मैं अपने घर के टुकड़े के लिए वापस स्टैक नहीं जोड़ूंगा क्योंकि यह मेरे आवेदन का होम पेज है। अगर AddToBackStack को HomeFragment में जोड़ें तो ऐप एक्यूट में सभी फ्रैक्शन को दूर करने के लिए इंतजार करेगा, फिर हमें खाली स्क्रीन मिलेगी, इसलिए मैं निम्नलिखित शर्त रख रहा हूं:

if (!(fragment instanceof HomeFragment)) {
            transaction.addToBackStack(null);
}

अब, आप Acitvity पर पहले जोड़े गए टुकड़े को देख सकते हैं और HomeFragment तक पहुंचने पर ऐप बाहर निकल जाएगा। आप निम्नलिखित स्निपेट पर भी देख सकते हैं।

@Override
public void onBackPressed() {

    if (mDrawerLayout.isDrawerOpen(Gravity.LEFT)) {
        closeDrawer();
    } else {
        super.onBackPressed();
    }
}

3

विखंडन: एक विधि बनाने एक BaseFragment बनाएं:

 public boolean onBackPressed();

गतिविधि:

@Override
public void onBackPressed() {
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            if (!fragment.isVisible()) continue;

            if (fragment instanceof BaseFragment && ((BaseFragment) fragment).onBackPressed()) {
                return;
            }
        }
    }

    super.onBackPressed();
}

आपकी गतिविधि संलग्न और दिखाई देने वाले टुकड़ों पर चलेगी और उनमें से प्रत्येक पर onBackPressed () कॉल करें और यदि उनमें से कोई एक 'सत्य' लौटाता है (जिसका अर्थ है कि इसे संभाला गया है, तो आगे कोई कार्यवाही नहीं)।


महोदय, यह सबसे सुंदर तरीका है और सही काम करता है!
asozcan

3

AndroidX रिलीज़ नोट्स के अनुसार , androidx.activity 1.0.0-alpha01जारी किया गया है और पेश करता है ComponentActivity, मौजूदा FragmentActivityऔर का एक नया आधार वर्गAppCompatActivity । और यह रिलीज हमें एक नई सुविधा प्रदान करती है:

अब आप अपनी गतिविधि में विधि को ओवरराइड किए बिना कॉलबैक प्राप्त करने के लिए एक के OnBackPressedCallbackमाध्यम addOnBackPressedCallbackसे पंजीकरण कर सकते हैं onBackPressed()


क्या आप इसका एक उदाहरण दिखा सकते हैं? मुझे वह तरीका नहीं सूझ रहा है।
ब्रायन ब्रायस

1
@BryanBryce मुझे एक उदाहरण नहीं मिला है लेकिन आधिकारिक डॉक्टर: डेवलपर.
android.com/reference/androidx/activity/…

विधि b / c को हल नहीं करेगी। AppCompatActivity वास्तव में androidx.act.ComponentActivity के बजाय androidx.activity.ComponentActivity से निकल रही है।
wooldridgetm

3

आप बैक प्रेस को संभालने के लिए गतिविधि में अंश को पंजीकृत कर सकते हैं:

interface BackPressRegistrar {
    fun registerHandler(handler: BackPressHandler)
    fun unregisterHandler(handler: BackPressHandler)
}

interface BackPressHandler {
    fun onBackPressed(): Boolean
}

उपयोग:

टुकड़े में:

private val backPressHandler = object : BackPressHandler {
    override fun onBackPressed(): Boolean {
        showClosingWarning()
        return false
    }
}

override fun onResume() {
    super.onResume()
    (activity as? BackPressRegistrar)?.registerHandler(backPressHandler)
}

override fun onStop() {
    (activity as? BackPressRegistrar)?.unregisterHandler(backPressHandler)
    super.onStop()
}

गतिविधि में:

class MainActivity : AppCompatActivity(), BackPressRegistrar {


    private var registeredHandler: BackPressHandler? = null
    override fun registerHandler(handler: BackPressHandler) { registeredHandler = handler }
    override fun unregisterHandler(handler: BackPressHandler) { registeredHandler = null }

    override fun onBackPressed() {
        if (registeredHandler?.onBackPressed() != false) super.onBackPressed()
    }
}

3

OnBackPressed को हैंडल करके कस्टम बैक नेविगेशन प्रदान करना अब टुकड़े के अंदर कॉलबैक के साथ अधिक आसान है।

class MyFragment : Fragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val onBackPressedCallback = object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                if (true == conditionForCustomAction) {
                    myCustomActionHere()
                } else  NavHostFragment.findNavController(this@MyFragment).navigateUp();    
        }
    }
    requireActivity().onBackPressedDispatcher.addCallback(
        this, onBackPressedCallback
    )
    ...
}

यदि आप कुछ शर्त के आधार पर डिफ़ॉल्ट बैक एक्शन चाहते हैं, तो आप उपयोग कर सकते हैं:

 NavHostFragment.findNavController(this@MyFragment).navigateUp();

3

टुकड़े की ऑनक्रिएट विधि के अंदर निम्नलिखित जोड़ें:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    OnBackPressedCallback callback = new OnBackPressedCallback(true) {
        @Override
        public void handleOnBackPressed() {
            //Handle the back pressed
        }
    };
    requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}

इस myFragment backpress को जोड़ने के बाद काम करता है, लेकिन अब गतिविधि backpress नहीं किया
सुनील चौधरी

2

सबसे अच्छा उपाय,

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;

public class BaseActivity extends AppCompatActivity {
    @Override
    public void onBackPressed() {

        FragmentManager fm = getSupportFragmentManager();
        for (Fragment frag : fm.getFragments()) {
            if (frag == null) {
                super.onBackPressed();
                finish();
                return;
            }
            if (frag.isVisible()) {
                FragmentManager childFm = frag.getChildFragmentManager();
                if (childFm.getFragments() == null) {
                    super.onBackPressed();
                    finish();
                    return;
                }
                if (childFm.getBackStackEntryCount() > 0) {
                    childFm.popBackStack();
                    return;
                }
                else {

                    fm.popBackStack();
                    if (fm.getFragments().size() <= 1) {
                        finish();
                    }
                    return;
                }

            }
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.