অ্যান্ড্রয়েডে অন্য একটি খণ্ডে নেভিগেট করার পরে কীভাবে নেভিগেশন স্ট্যাক সাফ করবেন


121

আমি অ্যান্ড্রয়েডে নতুন নেভিগেশন আর্কিটেকচার উপাদান ব্যবহার করছি এবং আমি একটি নতুন খণ্ডে যাওয়ার পরে নেভিগেশন স্ট্যাক সাফ করতে আটকে রয়েছি।

উদাহরণ: আমি লগইনফ্রেগমেন্টে আছি এবং আমি চাই যখন আমি হোম ফ্রেমে নেভিগেট করব তখন স্ট্যাকটি থেকে এই টুকরোগুলিটি সাফ হয়ে যাবে যাতে ব্যবহারকারী যখন পিছনের বোতামটি টিপবে তখন লগইনফ্র্যাগমেন্টে ফিরে না আসতে পারে।

আমি নেভিগেট করার জন্য একটি সরল নাভহস্টফ্রেগমেন্ট.ফাইন্ডনাভকন্ট্রোলার (টুকরা) .নভিগেট (আর। আইডহোমফ্রেগমেন্ট) ব্যবহার করছি ।

বর্তমান কোড:

mAuth.signInWithCredential(credential)
            .addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment);
                    } else {
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                    }
                }
            });

আমি ব্যবহার করার চেষ্টা NavOptions মধ্যে নেভিগেট করুন () কিন্তু ব্যাক বোতাম এখনও loginFragment ফিরে আমাকে পাঠাচ্ছে

NavOptions.Builder navBuilder = new NavOptions.Builder();
NavOptions navOptions = navBuilder.setPopUpTo(R.id.homeFragment, false).build();   
             NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment, null, navOptions);

আপনি ব্যাকস্ট্যাক সরবরাহ সরবরাহ করতে popBackStackবা যোগ LoginFragmentকরতে পারবেন না এবং এটিকে নতুন দিয়ে প্রতিস্থাপন করতে পারেনnulladdToBackStack(null);Fragment
ইউপি

দয়া করে আপনার পোস্টটি সম্পাদনা করুন এবং নেভিগেট করতে আপনি এখন যে কোডটি ব্যবহার করছেন তা যুক্ত করুন
বার্নস ২

আমি আমার প্রশ্নটি সম্পাদনা করেছি এবং আমার কোড যুক্ত করেছি
ইউসুফ এল বেহি

আমি মনে করি @ ইউপি একটি ভাল পরামর্শ দিয়েছে। অথবা আপনি যেমন navigate()পদ্ধতিটি ব্যবহার করতে পারেন navigate(int resId, Bundle args, NavOptions navOptions)এবং NavOptionsআপনার সেনেরিওর জন্য সবচেয়ে উপযুক্ত উপযুক্ত তা সরবরাহ করতে পারেন
বার্নস

আমি নাভোপশনগুলি ব্যবহার করার চেষ্টা করেছি তবে ফিরে বোতামটি এখনও আমাকে লগইনফ্র্যাগমেন্টে পাঠাচ্ছে
ইউসুফ এল বেহি

উত্তর:


179

প্রথমে বৈশিষ্ট্যগুলি app:popUpTo='your_nav_graph_id'এবং app:popUpToInclusive="true"ক্রিয়া ট্যাগে যুক্ত করুন।

<fragment
    android:id="@+id/signInFragment"
    android:name="com.glee.incog2.android.fragment.SignInFragment"
    android:label="fragment_sign_in"
    tools:layout="@layout/fragment_sign_in" >
    <action
        android:id="@+id/action_signInFragment_to_usersFragment"
        app:destination="@id/usersFragment"
        app:launchSingleTop="true"
        app:popUpTo="@+id/main_nav_graph"
        app:popUpToInclusive="true" />
</fragment>

দ্বিতীয়ত, পরামিতি হিসাবে উপরের ক্রিয়াটি ব্যবহার করে গন্তব্যে নেভিগেট করুন।

findNavController(fragment).navigate(
     SignInFragmentDirections.actionSignInFragmentToUserNameFragment())

দস্তাবেজগুলি দেখুনআরও তথ্যের জন্য ।

দ্রষ্টব্য : আপনি যদি পদ্ধতিটি ব্যবহার করে নেভিগেট করেন তবে আপনি navigate(@IdRes int resId)পছন্দসই ফলাফল পাবেন না। সুতরাং, আমি পদ্ধতি ব্যবহার navigate(@NonNull NavDirections directions)


1
ক্লিয়ারটাস্ক হিসাবে সেরা উত্তরটি এখন অ্যান্ড্রয়েড নেভিগেশন উপাদানগুলির নতুন সংস্করণগুলিতে হ্রাস করা হয়েছে!
মিচা জিওব্রো

14
কেউ এর মতো অ্যাকশনটির findNavController(fragment).navigate(R.id.action_signInFragment_to_usersFragment)
আইডিও

1
অসাধারণ! যাইহোক, এখন আমার কাছে ব্যাক / আপ গ্লাইফ রয়েছে তবে এটি টিপলে কিছুই হয় না। এটি অপসারণ করার একটি পরিষ্কার উপায় কী?
ডেনিশ খান

6
আমি "popUpTo" (যা আপনার বর্তমান টুকরা এবং আইডি যে আপনি এই যুক্তি পাস প্রথম সংঘটন মধ্যে সব টুকরা সরিয়ে ফেলা হবে) সেট করা হয় যে এই উত্তর মিথ্যা চাবিকাঠি মনে গৌণ গ্রাফ নিজেই আইডি । কার্যকরভাবে পুরোপুরি ব্যাকস্ট্যাক সাফ করা। কেবলমাত্র এই মন্তব্যটি যুক্ত করা কারণ আমি এটিকে ঠিক এর মতো ব্যাখ্যা করতে দেখিনি, এবং এটিই আমি খুঁজছিলাম। +1 টি!
স্কট ও'টুল

7
দ্রষ্টব্য : আপনি সেফ-আরগস গ্রেডেল অন্তর্ভুক্ত না করলে "দিকনির্দেশ" শ্রেণি তৈরি করা হবে না। আরও তথ্যের জন্য এখানে যান
জয়দীপ কালকানি

28

আমার ক্ষেত্রে আমার কোনও নতুন খণ্ড খোলার আগে আমার পিছনের স্ট্যাকের সমস্ত কিছুই সরিয়ে ফেলতে হবে যাতে আমি এই কোডটি ব্যবহার করি

navController.popBackStack(R.id.fragment_apps, true);
navController.navigate(R.id.fragment_company);

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



1
বর্তমান খণ্ড। আপনি যদি টুকরো টুকরোতে থাকেন এবং টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো ব্যবহারের প্রয়োজন হয় তবে আপনাকে অনেকটা নেভকন্ট্রোলআরপপব্যাকস্ট্যাক (R.id.fragmentOne, সত্য) ব্যবহার করতে হবে; navController.navigate (R.id.fragmentTwo);
বিবেণী

26

আমি মনে করি আপনার প্রশ্নটি কীভাবে পপ আচরণ / পপ টু / অ্যাপ্লিকেশনটি ব্যবহার করবে: পপআপটি (এক্সএমএল)

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

উদাহরণ (সরল চাকরির শিকারের অ্যাপ্লিকেশন)
আমার স্টার্ট_স্ক্রিন_নভ গ্রাফটি এরকম:

startScreenFragment (start) -> loginFragment -> EmployerMainFragment

                            -> loginFragment -> JobSeekerMainFragment

যদি আমি নেভিগেট করতে চাই EmployerMainFragmentএবং সমস্ত সহ পপ করতে চাই startScreenFragmentতবে কোডটি হ'ল:

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"
            app:popUpToInclusive="true" />

যদি আমি নেভিগেট করতে EmployerMainFragmentএবং বাদ দিয়ে সমস্ত পপ করতে চাই startScreenFragmentতবে কোডটি হবে:

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"/>

যদি আমি নেভিগেট করতে চান EmployerMainFragmentএবং পপ loginFragmentকিন্তু না startScreenFragment তারপর কোড হতে হবে:

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/loginFragment"
            app:popUpToInclusive="true"/>

অথবা

        <action
            android:id="@+id/action_loginFragment_to_employerMainFragment"
            app:destination="@id/employerMainFragment"

            app:popUpTo="@+id/startScreenFragment"/>

এক্সএমএলের পরিবর্তে এই প্রোগ্রামটিমেটিকভাবে কীভাবে করবেন?
ইগোরগানাপলস্কি

14

দ্রষ্টব্য: পরিষ্কার টাস্কটি অবহেলা করা হয়েছে, সরকারী বিবরণ

এই পদ্ধতিটি হ্রাস করা হয়। নাভকন্ট্রোলারের গ্রাফের আইডি সহ সেটপপআপ (ইনট, বুলিয়ান) ব্যবহার করুন এবং সত্যকে অন্তর্ভুক্ত করে সেট করুন।

পুরানো উত্তর

আপনি যদি কোডটিতে থাকা সমস্ত ফাজ দেখতে চান না, আপনি কেবল ক্রিয়াটির বৈশিষ্ট্যগুলিতে চেক Clear Taskইন করতে পারেন Launch Options

বিকল্পগুলি চালু করুন

সম্পাদনা করুন: অ্যান্ড্রয়েড স্টুডিও ৩.২ বিটা ৫ অনুসারে ক্লিয়ার টাস্ক আর আরম্ভ করার বিকল্প উইন্ডোতে দৃশ্যমান নয়, তবে আপনি এখনও এটিকে যোগ করে অ্যাকশন ট্যাগে নেভিগেশনের এক্সএমএল কোডটিতে ব্যবহার করতে পারেন

app:clearTask="true"

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

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

আমি আসলে এমন একটি সমস্যার মুখোমুখি হচ্ছি যেখানে এটি শুরু গন্তব্য নিয়ে হতাশায় নয়।
মেল

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

না, এটি আসলে আর ব্যবহার করা উচিত নয়। পরিবর্তে আপনার পপআপটি অন্তর্ভুক্তভাবে ব্যবহার করা উচিত। আমার পপআপ ব্যবহারের সন্ধানের সাথে আমি খুব শীঘ্রই উত্তরটি আপডেট করব।
মেল

5

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

আমাকে। সেটক্র্লেয়ারটাস্ক (সত্য) একটি নাওঅপশন হিসাবে নির্দিষ্ট করতে হয়েছিল।

mAuth.signInWithCredential(credential)
            .addOnCompleteListener(getActivity(), new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "signInWithCredential:success");


                        NavOptions.Builder navBuilder = new NavOptions.Builder();
                        NavOptions navOptions = navBuilder.setClearTask(true).build();
                        NavHostFragment.findNavController(LoginFragment.this).navigate(R.id.homeFragment,null,navOptions);
                    } else {
                        Log.w(TAG, "signInWithCredential:failure", task.getException());

                    }

                }
            });

2
আপনি আমার ব্যবহারের পরামর্শটি প্রয়োগ করতে সক্ষম হয়েছেন তা দেখে খুশী হলেনnavigate(int resId, Bundle args, NavOptions navOptions)NavOptions
বার্নস

হ্যাঁ. ধন্যবাদ @ বার্নস
ইউসুফ এল বেহি

14
হ্যাঁ "সেটক্লেয়ারটাস্ক" অবমূল্যায়ন করা হয়েছে তবে পরিবর্তে আপনি এটি ব্যবহার করতে পারেন: val navOptions = NavOptions.Builder().setPopUpTo(R.id.my_current_frag, true).build() findNavController().navigate(R.id.my_next_frag, null, navOptions)
পাবলো রেইস

1
@ সি-আন এটি কাজ করা উচিত। সম্ভবত আপনি একটি ভুল গন্তব্য খণ্ড ব্যবহার করছেন (উদাহরণস্বরূপ R.id.my_next_fragলগইন বা স্প্ল্যাশ স্ক্রিনের মতো হতে পারে); এছাড়াও আপনি popBack মাত্র এক চান, আপনি ব্যবহার করতে পারেন: NavHostFragment.findNavController(this).popBackStack()
পাবলো রেয়েস

2
@ পাবলোরেইস এটি সঠিক উত্তর। কেবল কোন খণ্ডটি সরানোর জন্য শেষ তা উল্লেখ করুন: বলুন আপনার কাছে এই স্ট্যাক রয়েছে: ফ্রেগমেন্ট_1 ফ্রেগমেন্ট_2 ফ্রেগমেন্ট_3 আপনি এখন ফ্রেগমেন্ট_3 এ রয়েছেন এবং ফ্রেগমেন্টে নেভিগেট করতে চান এবং অন্য সমস্ত টুকরা সাফ করতে চান। নেভিগেশনে কেবলমাত্র xML: অ্যাপ্লিকেশন: পপআপপো = "@ আইডি / ফ্রেগমেন্ট_1" অ্যাপ্লিকেশনটি উল্লেখ করুন: পপআপটিওআইক্লুসিভ = "সত্য"
ব্যবহারকারী3193413

5

আমি এখানে এটি কীভাবে করছি।

 //here the R.id refer to the fragment one wants to pop back once pressed back from the newly  navigated fragment
 val navOption = NavOptions.Builder().setPopUpTo(R.id.startScorecardFragment, false).build()

//now how to navigate to new fragment
Navigation.findNavController(this, R.id.my_nav_host_fragment)
                    .navigate(R.id.instoredBestPractice, null, navOption)

আপনার সমেত পতাকা কেন false?
ইগোরগানাপলস্কি

2
ডকুমেন্টেশন অনুসারে inclusive boolean: true to also pop the given destination from the back stack সুতরাং, আমি অন্তর্ভুক্তিকে মিথ্যা হিসাবে সেট করেছি কারণ আমি বর্তমান খণ্ডটিকে স্ট্যাক থেকে পপ করতে চাই না।
আবদুল রহমান শামায়ার

4
    NavController navController 
    =Navigation.findNavController(requireActivity(),          
    R.id.nav_host_fragment);// initialize navcontroller

    if (navController.getCurrentDestination().getId() == 
     R.id.my_current_frag) //for avoid crash
  {
    NavDirections action = 
    DailyInfoSelectorFragmentDirections.actionGoToDestionationFragment();

    //for clear current fragment from stack
    NavOptions options = new 
    NavOptions.Builder().setPopUpTo(R.id.my_current_frag, true).build();
    navController.navigate(action, options);
    }

1

আপনি এইভাবে বেস ক্রিয়াকলাপটির পিছনে চেপে থাকা ওভাররাইড করতে পারেন:

override fun onBackPressed() {

  val navigationController = nav_host_fragment.findNavController()
  if (navigationController.currentDestination?.id == R.id.firstFragment) {
    finish()
  } else if (navigationController.currentDestination?.id == R.id.secondFragment) {
    // do nothing
  } else {
    super.onBackPressed()
  }

}

1

দ্রষ্টব্য: এটি প্রকৃত প্রশ্নের সাথে সম্পর্কিত নাও হতে পারে।

নেভিগেশন রক্ষণাবেক্ষণের জন্য যদি কোনও খণ্ডের একক উদাহরণ প্রয়োজন হয় তবে এই পদ্ধতিটি কার্যকর হবে ।

// imports
import androidx.navigation.navOptions

// navigate to fragment
navController.navigate(R.id.nav_single_instance_fragment, null,
                            navOptions {
                                popUpTo = R.id.nav_single_instance_fragment
                                launchSingleTop = true
                            })

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

    def nav_version = "2.2.0"
    implementation "androidx.navigation:navigation-ui:$nav_version"
    implementation "androidx.navigation:navigation-fragment:$nav_version"
    implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
    implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

0

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

সহজ সমাধানটি ছিল একটি গ্লোবাল অ্যাকশন তৈরি করা যা গন্তব্যটির দিকে ইঙ্গিত করে যা ব্যবহারকারীকে থাকা উচিত। আপনাকে app:popUpTo="..."সঠিকভাবে সেট করতে হবে - আপনি পপ আপ করতে চান এমন গন্তব্যে সেট করুন। আমার ক্ষেত্রে এটি আমার পরিচয় বার্তা ছিল। সেটও করেছেনapp:popUpToInclusive="true"


0

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

পূর্ববর্তী স্ক্রিনে যেতে:

<action
        android:id="@+id/action_deleteEmployeeFragment_to_employeesListFragment2"
        app:destination="@id/employeesListFragment"/>


    btn_cancel.setOnClickListener {
                it.findNavController().popBackStack()
            }

পূর্ববর্তী সমস্ত ব্যাকস্ট্যাক সাফ করার জন্য এবং নতুন স্ক্রিনে যান:

<action
        android:id="@+id/action_deleteEmployeeFragment_to_employeesListFragment2"
        app:destination="@id/employeesListFragment"
        app:popUpTo="@id/employeesListFragment"
        app:popUpToInclusive="true"
        app:launchSingleTop="true" />


 btn_submit.setOnClickListener {
                   it.findNavController().navigate(DeleteEmployeeFragmentDirections.actionDeleteEmployeeFragmentToEmployeesListFragment2())
        }

আরও রেফারেন্সের জন্য: জেটপ্যাক নেভিগেশন উদাহরণ


0

আপনি যেমন সহজ করতে পারেন:

getFragmentManager().popBackStack();

আপনি যদি গণনাটি পরীক্ষা করতে চান তবে আপনি এটি করতে পারেন:

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