টুকরাগুলিতে অনব্যাকপ্রেসড () কীভাবে প্রয়োগ করবেন?


459

onBackPressed()অ্যান্ড্রয়েড ক্রিয়াকলাপে আমরা যেভাবে প্রয়োগ করি তার অনুরূপ কি এমন কোনও উপায় আছে যার মাধ্যমে আমরা অ্যান্ড্রয়েড ফ্রেগমেন্টে প্রয়োগ করতে পারি?

ফ্রেগমেন্ট লাইফসাইকেলে যেমন নেই onBackPressed()। ওইখানে যাত্রায় অন্য কোন বিকল্প পদ্ধতি onBackPressed()অ্যান্ড্রয়েড 3.0 টুকরা কি?


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

61
সমস্ত খণ্ড যখন ওয়েবভিউ প্রদর্শনের জন্য করে এবং আপনি কী করতে চান যখন ওয়েব বোতামটি পূর্বের পৃষ্ঠায় "ফিরে যেতে" পারে যখন পিছনের বোতামটি টিপানো হয়?
মার্পার

মাইকেল হার্বিগ উত্তর আমার জন্য নিখুঁত ছিল। তবে যারা ব্যবহার করতে পারবেন না তাদের জন্য getSupportFraamentManager () ব্যবহার করুন। পরিবর্তে getFragmentManager () ব্যবহার করুন।
ড্যান্টালিয়ান

[অনুরূপ প্রশ্ন] [১] সম্পর্কে দিমিত্রি জয়েটসেভের উত্তরটি ঠিক ঠিক কাজ করে। [1]: stackoverflow.com/a/13450668/1372866
ashakirov

6
মোহ্পারের উত্তর দেওয়ার জন্য আপনি ওয়েবউভিউ.সেটঅনকিএলাইস্টেনার (নতুন অনকাইলিস্টনার () {@ ওভাররাইড পাবলিক বুলিয়ান অনকি (ভি, ইন কী কীড, কীভেন্থ ইভেন্ট দেখুন) {যদি (কীকোড == কীআভেন্ট.কি.ইসি.সি.ডি.বি.এইচ. ও ওয়েবভিউ.কেনব্যাক) ( {webview.goBack (); সত্য প্রত্যাবর্তন;} মিথ্যা প্রত্যাবর্তন;}});
ওমিদ আমিনিভা 21

উত্তর:


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
যদি আপনি সমর্থন ভি 7 লাইব্রেরি ব্যবহার করেন এবং আপনার ক্রিয়াকলাপটি ফ্রেগমেন্টএকটিভিটি (বা একটি উপক্লাস, যেমন অ্যাপকোম্প্যাটএকটিভিটি) থেকে প্রসারিত হয় তবে এটি ডিফল্টরূপে ঘটবে। দেখুন FragmentActivity # onBackPressed
জিয়াও

3
তবে আপনি এই
কোডটিতে

2
@ প্র্রাবগুলি যদি আপনি সমর্থন ভি 4 টুকরা ব্যবহার করে থাকেন তবে নিশ্চিত হন যে আপনি getSupportFraamentManager () ব্যবহার করছেন get 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? ফ্র্যাগমেন্টপেজারের জন্য এটি কি আইডি?
নাথান এফ।

1
@ ম্যাক্সিমজাল্লু কোটলিন সমাধানে, নিরাপদ কল ( .?) মিশ্রিত করা এবং নন- !!নালগুলি প্রয়োগ করা এনপিইগুলিতে নিয়ে যেতে পারে - castালাই সর্বদা নিরাপদ থাকে না। আমি বরং লিখতে if ((fragment as? IOnBackPressed)?.onBackPressed()?.not() == true) { ... }বা আরও কোটলনি(fragment as? IOnBackPressed)?.onBackPressed()?.not()?.let { ... }
Antek

1
@ আন্টেক হ্যালো, আপনার ফিরে আসার জন্য আপনাকে ধন্যবাদ, আপনি সংশোধন করতে পোস্টটি সম্পাদনা করতে পারতেন। সামগ্রিক সমাধানটি কঠোরভাবে বিচার করবেন না।
ম্যাক্সিমিম জল্লু

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() }এটি কোটলিন এবং নেভিগেশন নিয়ন্ত্রণকারী
প্যাভলে পাভলভ

97

@ হাইএমপিআরডের মতে উত্তরটি এখানে কীভাবে কাজ করা উচিত তা সিউডোকোড। আসুন এটি বলতে দিন যে আপনার মূল ক্রিয়াকলাপটিকে বলা হয় 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 }});
ডেডফিশ

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


এটি আমার পক্ষে নিখুঁতভাবে কাজ করেছে, আমি ক্রিয়াকলাপটি পুনরায় চালু করি
rapelbgr

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
নির্দোষভাবে কাজ করেছেন! তবে তারপরে আপনাকে ডিফল্ট ক্রিয়াটিও পরিচালনা করতে হবে, সম্ভবত আরও একটি আইফ শর্ত লিখে। যেহেতু, আমি আমার স্লাইডআপপ্যানেলটি প্রসারিত করে নিচে নামিয়ে দিচ্ছিলাম। সুতরাং, আমি প্রথমে একটি চেক চিহ্নিত করতে হয়েছিল (প্যানেলটি আপ থাকলে) তারপরে .....
Sud007

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

এটি দুঃস্বপ্নের জন্য একটি দুর্দান্ত সহজ সমাধান যা টুকরো টুকরো। আপনার যদি একটি 'জটিল' সম্পাদনা ফর্ম থাকে তবে আপনার সম্ভবত আপনার প্রকল্পটি মুছে ফেলা উচিত। মানক আচরণ ব্যবহার করতে চাইলে মিথ্যা প্রত্যাবর্তন করুন। সত্য ফিরুন তুমি কখন ফিরে প্রেস বাধাপ্রাপ্ত করেছেন এবং এটি সঙ্গে কিছু কাজ করেছেন
behelit

65

আপনি যদি এই ধরণের কার্যকারিতা চেয়েছিলেন তবে আপনার ক্রিয়াকলাপে আপনাকে এটিকে ওভাররাইড করতে হবে এবং তারপরে YourBackPressedআপনার সমস্ত টুকরাগুলিতে একটি ইন্টারফেস যুক্ত করতে হবে, যখনই পিছনের বোতামটি টিপানো হয় আপনি প্রাসঙ্গিক টুকরোটিতে কল করেন।

সম্পাদনা: আমি আমার পূর্ববর্তী উত্তর সংযোজন করতে চাই।

যদি আমি আজ এটিই করতাম তবে আমি অন্য একটি প্যানেলগুলি মাস্টার / প্রধান সামগ্রী প্যানেলে একযোগে আপডেট করার আশা করি যদি আমি একটি সম্প্রচার বা সম্ভবত অর্ডার করা সম্প্রচার ব্যবহার করতাম।

LocalBroadcastManagerসমর্থন লাইব্রেরিতে এটির সাথে সহায়তা করতে পারে এবং আপনি কেবল সম্প্রচারটি প্রেরণ করুন onBackPressedএবং আপনার যত্নবান অংশে সাবস্ক্রাইব করুন। আমি মনে করি যে মেসেজিং একটি আরও decoupled বাস্তবায়ন এবং আরও ভাল স্কেল হবে, এখন এটি আমার অফিসিয়াল বাস্তবায়ন সুপারিশ হবে। Intentআপনার বার্তার জন্য ফিল্টার হিসাবে এর ক্রিয়াটি কেবল ব্যবহার করুন । আপনার সদ্য নির্মিত প্রেরণ করুন ACTION_BACK_PRESSED, আপনার ক্রিয়াকলাপ থেকে এটি প্রেরণ করুন এবং প্রাসঙ্গিক টুকরোতে এটি শুনুন।


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

2
আমি স্কোয়ার ইভেন্টবাসটি এখনও ব্যবহার করি নি, তবে আমি ভবিষ্যতের পণ্যগুলিতে থাকব। আমি মনে করি এটি আরও ভাল খাঁটি-জাভা সমাধান, এবং যদি আপনি আপনার আর্কিটেকচারের অ্যান্ড্রয়েড বিভাগগুলি নক করতে পারেন তবে আরও ভাল।
হাউএমইআরইডি

কীভাবে আপনি কেবলমাত্র শীর্ষ টুকরোগুলি ইভেন্টটি পরিচালনা করতে দেবেন? উদাহরণস্বরূপ, আপনি বর্তমানে প্রদর্শিত খণ্ডটি ধ্বংস করতে চান
ইউজেন

আপনি যদি এটি ব্যবহার করে থাকেন তবে ব্রডকাস্ট রিসিভারটি জীবনচক্রের সাথে আবদ্ধ হওয়া উচিত, সুতরাং যখন এটি দৃশ্যমান না হয় এটি ইভেন্টটি গ্রহণ করা উচিত নয়।
HaMMeReD

এছাড়াও খেয়াল করুন যে LocalBroadcastManagerঅর্ডার করা সম্প্রচারগুলি করতে পারে না
জিয়াও

46

এর কোনওটিই কার্যকর করা সহজ নয় এবং এটি সর্বোত্তম উপায়ে কাজ করবে না।

খণ্ডগুলিতে ডেটাচ একটি পদ্ধতি কল রয়েছে যা কাজটি করবে।

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

এই কাজটি করবেন।


20
তবে এখানে সমস্যাটি হ'ল আপনি জানেন না যে কোনও অংশটি কোনও ব্যাক প্রেসের কারণে বা অন্য কোনও ক্রিয়াকলাপের কারণে এই খণ্ডটি বিযুক্ত হয়েছিল কিনা, যার ফলে ব্যবহারকারীকে অন্য কোনও ক্রিয়াকলাপ বা খণ্ড খণ্ডিত করে।
সানি

7
যখন খণ্ডটি তার ক্রিয়াকলাপের সাথে আর সংযুক্ত থাকে না তখন onDetach () বলা হয়। এটি অনস্ট্রোয়ার () পরে বলা হয়। যদিও আপনি পিছনের বোতামটি টিপলে আপনি এই কোডটিতে পৌঁছে যাবেন যখন আপনি খণ্ড থেকে খণ্ডে পরিবর্তন করবেন তখন আপনি এই কোডটি পাবেন। আপনি এই কাজটি করার জন্য নিফটি কিছু করতে পারেন যদিও ...
apmartin1991

একটি ডায়ালগফ্র্যাগমেন্টের জন্য সূক্ষ্ম কাজ করে।
কুলমাইন্ড

2
স্ট্যাকওভারফ্লো . com/a/27103891/2914140 তেisRemoving() বর্ণিত হিসাবে যুক্ত করতে ভুলবেন না ।
কুলমাইন্ড

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/navication/navication-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)তবে এটি নিজেই তা পরিচালনা করবে তবে আপনি যদি কোনও ট্যাগ দেন তবে আপনার নিজের হাতে এটি পরিচালনা করা উচিত।


অ্যাডটোব্যাকস্ট্যাক পদ্ধতি যুক্ত করার মতো আরও কিছু করার দরকার আছে কি না?
শ্রীচরণ দেশবাতুল

1
যদি আপনি কেবল যুক্ত করেন যে এটির কাজ করা উচিত, যদি এটি এখনও কাজ না করে তবে আপনার কোডে কিছু থাকা উচিত। কোড কোথাও করে যান @SreecharanDesabattula দেখতে
রুডি


20

যেহেতু এই প্রশ্ন এবং উত্তরগুলির কয়েকটি পাঁচ বছরেরও বেশি পুরানো, তাই আমার সমাধানটি ভাগ করে নেওয়া যাক। এটি @ অয়েনিগুনের উত্তরটির অনুসরণ এবং আধুনিকীকরণ

হালনাগাদ: এই নিবন্ধের নীচে, আমি একটি অ্যাবস্ট্রাক্ট ফ্র্যাগমেন্ট এক্সটেনশন ব্যবহার করে একটি বিকল্প বাস্তবায়ন যুক্ত করেছি যা ক্রিয়াকলাপের সাথে জড়িত হবে না, যা আরও জটিল কাঠামোগুলি হায়ারার্কিযুক্ত নেস্টেড টুকরো জড়িত যেগুলির জন্য বিভিন্ন ব্যাক আচরণ প্রয়োজন 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()ব্যাক বোতামটি যা করছেন তার জন্য যদি হ্যান্ডলিংয়ের প্রয়োজন না হয় তবে আপনি ক্রিয়াকলাপ পদ্ধতিটি কল করেছেন কিনা তা নিশ্চিত করুন , অন্যথায়, পিছনের বোতামটি অক্ষম হয়ে যাবে ... এবং আপনি এটি চান না!

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

আমি আশা করি যে কেউ এই দরকারী খুঁজে পেয়েছে। শুভ কোডিং।


ধন্যবাদ, এটি একটি দুর্দান্ত সমাধান। আপনি কি বলতে পারবেন, আপনি super.onBackPressed();দু'বার ফোন করলেন কেন ?
কুলমাইন্ড

একে নাল অবস্থা সম্পর্কে একবার দৃশ্যে একবার বলা হয় currentFragment। যদি খণ্ডটি শূন্য না হয় এবং খণ্ডটি Backableইন্টারফেসটি প্রয়োগ করে , কোনও পদক্ষেপ নেওয়া হবে না। যদি খণ্ডটি শূন্য না হয় এবং এটি কার্যকর না হয় Backable, আমরা সুপার পদ্ধতিটি কল করি। যদি খণ্ডটি শূন্য থাকে তবে এটি সর্বশেষ সুপার কল এড়িয়ে যায়।
mwieczorek

দুঃখিত, আমি বুঝতে পারি না। সেক্ষেত্রে যখন currentFragmentকোনওটি নাল নয় এবং এটি ব্যাকবলের একটি উদাহরণ এবং এটি আলাদা করা হয় (আমরা backবোতাম টিপে টুকরোটি বন্ধ করি) এর প্রথম super.onBackPressed();উপস্থিতি বলা হয়, তারপরে দ্বিতীয়টি।
কুলমাইন্ড 13'8

দুর্দান্ত সমাধান
ডেভিড টলেডো

সম্ভবত "ক্লোজযোগ্য" "ব্যাকটেবল" এর চেয়ে কিছুটা ভাল লাগছে
পুমনও

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() ক্রিয়াকলাপটি ক্রিয়াকলাপ থেকে বিচ্ছিন্ন করে দিন।

@ স্টার্লিং ডিয়াজের উত্তর অনুসারে আমি মনে করি তিনি ঠিক আছেন। তবে কিছু পরিস্থিতি ভুল হবে। (উদা। পর্দার আবর্তন)

সুতরাং, আমি মনে করি আমরা 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?
}

তারপরে ক্রিয়াকলাপে কেবলমাত্র অনব্যাকড্রেসডকে ওভাররাইড করুন

    @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;
}

কাজ করছে না ! সুপার.ব্যাকপ্রেসড () সর্বদা ডাকা হয় :(
অনিমেষ মঙ্গলা

এই ইভেন্টটি কীভাবে পাস করবেন ইনার টুকরা। আমার ক্রিয়াকলাপে ভিউপেজার এবং ভিউপ্যাজারের টুকরোগুলি রয়েছে, এখন সেই সমস্ত খণ্ডে শিশু খণ্ড রয়েছে। কীভাবে সেই শিশুটির টুকরোয় পিছনে বাটন ইভেন্টটি পাস করবেন।
কিশান ভাঘেলা

@ কিশনবাঘেলা ভাল আমি তখন থেকে অ্যান্ড্রয়েড স্পর্শ করতে পারি নি তবে আমার একটি ধারণা আছে। আমার উত্তর আপডেট করার জন্য আমাকে 24 তম দিন।
Bżażej

ঠিক আছে কোন সমস্যা নেই, একটি বিকল্প হ'ল আমাকে শ্রোতার ইভেন্টটি পিতা-মাতার টুকরা থেকে প্রতিটি শিশু খণ্ডে প্রেরণ করা দরকার। তবে এটি আদর্শ উপায় নয় কারণ আমার প্রতিটি খণ্ডের জন্য এটি করা দরকার।
কিশান ওয়াঘেলা 24'16

@ কিশনবাঘেলা আমি ক্রিয়াকলাপে পরিচালক সম্পর্কে ভাবছিলাম। আপনি এই ইন্টারফেসের সাথে টুকরা যোগ / মুছে ফেলতে পারেন। তবে এই পদ্ধতির সাহায্যে আপনার প্রতিটি বিভাগে ম্যানেজার প্রয়োগ করতে হবে যার সাবফ্র্যামেন্ট রয়েছে। সুতরাং সম্ভবত আরও ভাল সমাধান সিঙ্গলটন হিসাবে পরিচালক তৈরি করা হবে। তারপরে আপনাকে টুকরো / অবজেক্টগুলিকে যুক্ত / অপসারণ করতে হবে এবং এই পরিচালকের 'অনব্যাকপ্রেসড' তে আপনি পদ্ধতিটি 'অনব্যাকপ্রেসড' বলবেন। এই পদ্ধতিটি ম্যানেজারে যুক্ত হওয়া প্রতিটি বস্তুর মধ্যে পদ্ধতিটিকে 'অনক্লিক' কল করবে। এটা কি কম-বেশি আপনার কাছে পরিষ্কার?
Bżażej

8

নীচের মত আপনার প্রকল্পে আপনার ইন্টারফেস যুক্ত করা উচিত;

public interface OnBackPressed {

     void onBackPressed();
}

এবং তারপরে, আপনার নিজের খণ্ডে এই ইন্টারফেসটি প্রয়োগ করা উচিত;

public class SampleFragment extends Fragment implements OnBackPressed {

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

}

এবং আপনি এই ব্যাকপ্রেসড ইভেন্টটিকে নীচের মত আপনার ব্যাকপ্রেসড ইভেন্টগুলিতে ক্রিয়াকলাপ করতে পারবেন;

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: স্ট্যাকের আকার 8MB"।
কুলমাইন্ড

8

এটি কেবল একটি ছোট কোড যা কৌশলটি করবে:

 getActivity().onBackPressed();

আশা করি এটি কাউকে সাহায্য করবে :)


4
তিনি আচরণটি ওভাররাইড করতে বলেছিলেন, কেবল ক্রিয়াকলাপের পদ্ধতিটি শুরু করার জন্য নয়।
mwieczorek

2
আমি এটি মনোযোগ সহকারে পড়েছি, ধন্যবাদ। তিনি কীভাবে ওভাররাইড করবেন জিজ্ঞাসা করলে আপনার সমাধানটি অনব্যাকপ্রেসড পদ্ধতিটিকে সরাসরি কার্যকলাপের সাথে সম্পর্কিত করে to
mwieczorek

7

আপনি যদি ইভেন্টবস ব্যবহার করেন তবে এটি সম্ভবত আরও অনেক সহজ সমাধান:

আপনার খণ্ডে:

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

ব্যাকপ্রেসডমেসেজ.জভা কেবল একটি পজো অবজেক্ট

এটি সুপার ক্লিন এবং কোনও ইন্টারফেস / বাস্তবায়নের ঝামেলা নেই।


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

অনডেট্রয়েভিউ () কীভাবে ব্যবহার করবেন?

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

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

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
     }
}

তারপরে আমার অনব্যাকপ্রেস বিকল্পটি খণ্ডগুলিতে ব্যবহারের জন্য প্রস্তুত।

সাব টুকরা

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

ক্রিয়াকলাপের জীবনচক্রের ক্ষেত্রে, অডিওরয়েড ব্যাক বোতামটি ফ্র্যাগমেন্টম্যানেজার লেনদেনের সাথে ডিল করে যখন আমরা ফ্রেগমেন্টএটিভিটি বা অ্যাপকোম্প্যাটঅ্যাক্টিভিটি ব্যবহার করি।

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

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

এখানে, আমি আমার বাড়ির খণ্ডের জন্য পিছনে স্ট্যাক যুক্ত করব না কারণ এটি আমার আবেদনের হোম পৃষ্ঠা page যদি হোমফ্র্যাগমেন্টে অ্যাড টোব্যাকস্ট্যাক যুক্ত করা হয় তবে অ্যাপটি সমস্ত ফ্রেমটিকে সংবেদনশীলতার সাথে অপসারণের জন্য অপেক্ষা করবে তবে আমরা ফাঁকা স্ক্রিন পাব তাই আমি নিম্নলিখিত শর্তটি রেখেছি,

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

এখন, আপনি অ্যাক্টিভিটিতে পূর্বের যোগ করা টুকরোটি দেখতে পাচ্ছেন এবং হোমফ্র্যাগমেন্টে পৌঁছে অ্যাপ্লিকেশনটি প্রস্থান করবে। আপনি নিম্নলিখিত স্নিপেটগুলিও দেখতে পারেন।

@Override
public void onBackPressed() {

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

3

খণ্ড: একটি পদ্ধতি রেখে বেসফ্রেগমেন্ট করুন:

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

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


স্যার, এটি সবচেয়ে মার্জিত উপায় এবং নিখুঁতভাবে কাজ করে!
asozcan

3

অ্যান্ড্রয়েডএক্স রিলিজ নোট অনুসারে , androidx.activity 1.0.0-alpha01প্রকাশিত হয়েছে এবং প্রচলিত হয় ComponentActivity, বিদ্যমান FragmentActivityএবং এর একটি নতুন বেস ক্লাস AppCompatActivity। এবং এই প্রকাশটি আমাদের কাছে একটি নতুন বৈশিষ্ট্য এনেছে:

আপনি এখন আপনার ক্রিয়াকলাপে পদ্ধতিটিকে ওভাররাইড করার প্রয়োজন ছাড়াই কলব্যাকগুলি গ্রহণের OnBackPressedCallbackমাধ্যমে একটি রেজিস্ট্রেশন করতে পারেন ।addOnBackPressedCallbackonBackPressed()


আপনি এর একটি উদাহরণ দেখাতে পারেন? সমাধানের জন্য আমি সেই পদ্ধতিটি পাচ্ছি না।
ব্রায়ান ব্রাইস

1
@ ব্রায়ানব্রাইস আমি সরকারী দস্তাবেজ ছাড়া উদাহরণ খুঁজে পেলাম না: developer.android.com/references/androidx/activity/…
টনিএল

পদ্ধতিটি বি / সি সমাধান করবে না অ্যাপকোম্প্যাটএটিভিটি প্রকৃতপক্ষে অ্যান্ড্রয়েড.স্যাক্টিভিটি.কম্পোনটিএকটিভিটির পরিবর্তে অ্যান্ড্রয়েড.কোড়.এপ.কম্পোনেন্ট অ্যাক্টিভিটি থেকে প্রসারিত হচ্ছে।
ওউলড্রিজেটেম

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

অনব্যাকপ্রেসড পরিচালনা করে কাস্টম ব্যাক নেভিগেশন সরবরাহ করা এখন খণ্ডের অভ্যন্তরে কলব্যাকগুলির সাথে আরও সহজ।

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

এই মাইগ্রাগমেন্ট ব্যাকপ্রেস যুক্ত করার পরে কাজ করে তবে এখন অ্যাক্টিভিটি ব্যাকপ্রেস করেনি
সুনীল চৌধুরী চৌধুরী

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

            }
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.