ব্যাকস্ট্যাক অন-রিজিউম () এবং অনপজ () কল করা হয় না


195

একটি ক্রিয়াকলাপের ভিতরে আমার একাধিক টুকরো রয়েছে। একটি বোতামে ক্লিক করে আমি একটি নতুন টুকরা শুরু করছি, এটি ব্যাকস্ট্যাকে যুক্ত করছি। আমি স্বাভাবিকভাবেই প্রত্যাশা করেছি যে onPause()বর্তমান খন্ডের পদ্ধতি এবং onResume()নতুন খণ্ডটির কল করা হবে। ভাল হচ্ছে না।

LoginFragment.java

public class LoginFragment extends Fragment{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      final View view  =   inflater.inflate(R.layout.login_fragment, container, false);
      final FragmentManager mFragmentmanager =  getFragmentManager();

      Button btnHome  = (Button)view.findViewById(R.id.home_btn);
      btnHome.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view){
           HomeFragment fragment    = new HomeFragment();
           FragmentTransaction ft2   =  mFragmentmanager.beginTransaction();
           ft2.setCustomAnimations(R.anim.slide_right, R.anim.slide_out_left
                    , R.anim.slide_left, R.anim.slide_out_right);
           ft2.replace(R.id.middle_fragment, fragment);
           ft2.addToBackStack(""); 
           ft2.commit();    
         }
      });
  }

  @Override
  public void onResume() {
     Log.e("DEBUG", "onResume of LoginFragment");
     super.onResume();
  }

  @Override
  public void onPause() {
    Log.e("DEBUG", "OnPause of loginFragment");
    super.onPause();
  }
}

HomeFragment.java

public class HomeFragment extends Fragment{
  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     final View view  =   inflater.inflate(R.layout.login_fragment, container, false);
  }

  @Override
  public void onResume() {
     Log.e("DEBUG", "onResume of HomeFragment");
     super.onResume();
  }

  @Override
  public void onPause() {
     Log.e("DEBUG", "OnPause of HomeFragment");
     super.onPause();
  }
}

আমি যা আশা করেছিলাম, তা ছিল,

  1. যখন বাটনে ক্লিক না LoginFragment দিয়ে প্রতিস্থাপিত পরার HomeFragment , onPause()এর LoginFragment এবং onResume()এর HomeFragment নামক পরার
  2. যখন ফিরে টেপা না হলে, HomeFragment আউট poped হয় এবং LoginFragment , এবং দেখা যায় onPause()এর HomeFragment এবং onResume()এর LoginFragment নামক পায়।

আমি যা পাচ্ছি তা হ'ল

  1. যখন বাটনে ক্লিক না HomeFragment সঠিকভাবে প্রতিস্থাপন করা হয় LoginFragment , onResume () এর HomeFragment বলা হয়, কিন্তু onPause (এর) LoginFragment কখনো বলা হয়।
  2. পিছনে চাপলে , হোমফ্র্যাগমেন্টটি সঠিকভাবে লগইনফ্রেগমেন্টটি প্রকাশের জন্য পপিং করছে , হোমফ্র্যাগমেন্টের অনপস () কল হয়ে যায়, তবে লগইনফ্রেগমেন্টের অনেসিউম () কখনই কল হয় না।

এটাই কি স্বাভাবিক আচরণ? কেন onResume()এর LoginFragment বলা হয় না পেয়ে যখন আমি ফিরে বোতামটি টিপুন।


ক্রিয়াকলাপটি যুক্ত করুন যা খণ্ডগুলি পরিচালনা করে।
18-18

আমার নমুনা সমস্যা হচ্ছে, কল না পেয়ে কল করুন, আপনি কীভাবে সমাধান করেছেন,
স্যাম

আমার একই সমস্যা ছিল তবে বুঝতে পেরেছি আমি ft2.add () ব্যবহার করছি; পরিবর্তে ft2.replace ()। কেবলমাত্র অন্য কারণ হ'ল যদি আপনার ক্রিয়াকলাপটি
খণ্ডটির

3
আমারও একই সমস্যা হচ্ছে। আমি লক্ষ্য করেছি যে .replace () প্রয়োজনীয় লাইফাইসাইকেল পদ্ধতিগুলি কল করবে, তবে এটি মূলত খণ্ডটিকে ধ্বংস করে। এছাড়াও, onSaveInstanceState বলা হয় না । যেমন, আমি এর রাজ্য রাখতে পারি না। সুতরাং, আমার অ্যাড ব্যবহার করা দরকার, তবে অনারিউম / পজ বলা হয় না :(
এরিয়েটস

এফডাব্লুআইডাব্লু, আমার অভিজ্ঞতাটি হ'ল লাইব্রেরির টুকরোটি ব্যাকস্ট্যাকটি ধাক্কা / পপিংয়ের সময় অন পজ এবং অন রেসুমিকে কল করে তবে অ্যানড্রয়েড অন্তর্নির্মিত টুকরোগুলি তা করে না। এখনও এটির জন্য উপযুক্ত কাজ খুঁজে পাওয়া যায় নি।
বেনকসি

উত্তর:


185

টুকরাগুলি onResume()বা onPause()ক্রিয়াকলাপ onResume()বা onPause()ডাকা হলেই ডাকা হবে। তারা শক্তভাবে মিলিত হয়Activity

এই নিবন্ধের খণ্ড লাইফসাইকেল হ্যান্ডলিং পড়ুন ।


1
নিবন্ধে বলা হয়েছে যে "একবার ক্রিয়াকলাপটি পুনরায় শুরু হওয়া অবস্থায় পৌঁছে গেলে আপনি অবাধে ক্রিয়াকলাপে টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো করে বদলে দিতে পারেন।" এর অর্থ কি এই যে অনক্রমে ক্রিয়াকলাপটি চালু না হওয়া সত্ত্বেও অনলাইনে কল করা যাবে?
v4r

3
4.4-এ দেশীয় (সমর্থন নয়) টুকরো টুকরো হিসাবে (এটি পুরানো সংস্করণগুলির জন্য সত্য কিনা তা নিশ্চিত নয়) অন পজ () এবং onResume () কেবলমাত্র যখন এই ইভেন্টগুলি ক্রিয়াকলাপে ঘটে তখনই ডাকা হয় না, তবে উদাহরণস্বরূপ যখন আপনি প্রতিস্থাপন () বা সংযোজন কল করবেন () / সরান () লেনদেন করার সময়, সুতরাং এই উত্তরটি অন্তত অ্যান্ড্রয়েডের সাম্প্রতিক সংস্করণের জন্য বিভ্রান্তিকর।
Dmide

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

1
সম্পর্কিত নয় যদিও কিন্তু আমি যখন আমার সমস্যার জন্য অনুসন্ধান করা এই প্রশ্নের পাওয়া onPause()পর বলা হচ্ছে onSaveInstanceState()পরিবর্তে এটা আগে। আপনি যদি আমার অন্য কোনও সন্তানের কাছে পুনরুত্পাদন করতে পারেন FragmentStatePagerAdapter(বলুন যে আপনি 0 থেকে শিশু 2 তে চলে যান, নিজের দিকে খেয়াল করুন, এটি ঘটে কারণ শিশু 2 খোলার সাথে সাথে শিশু 0 নষ্ট হয়ে যায় )
সুফিয়ান

আপনি কি বোঝাতে চেয়েছেন তা নিশ্চিত না। Ft.replace কল করার জন্য অনপজ (প্রতিস্থাপিত খণ্ডটির) এবং onResume (প্রতিস্থাপনের খণ্ডটির) ট্রিগার করা উচিত। এটি কোনও ক্রিয়াকলাপ ছাড়াই করা হয় ...
ডেভিড রেফেলি

20
  • যেহেতু আপনি ব্যবহার করেছেন ft2.replace(), FragmentTransaction.remove() পদ্ধতিটি কল করা হয় এবং এটি Loginfragmentসরানো হবে। পড়ুন এই । সুতরাং onStop()এর LoginFragmentপরিবর্তে বলা হবে onPause()। (নতুন খণ্ডটি পুরানোটিকে পুরোপুরি প্রতিস্থাপন করে)।
  • কিন্তু যেহেতু আপনি এটিও ব্যবহার করেছেন ft2.addtobackstack(), রাজ্যের Loginfragmentএকটি বান্ডিল হিসাবে সংরক্ষণ করা হবে এবং আপনি বোতাম থেকে ফিরে ক্লিক HomeFragment, onViewStateRestored()দ্বারা অনুসরণ ডাকা হবে onStart()এর LoginFragment। সুতরাং শেষ পর্যন্ত onResume()বলা হবে না।

1
onViewStateRestoredআপনার যদি বলা হয়setRetainInstance(true)
ফরিদ

14

এখানে গরের উত্তরের আমার আরও দৃ version় সংস্করণটি (টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো করার পরেও অবিশ্বাস্য)

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if (getFragmentManager() != null) {

                Fragment topFrag = NavigationHelper.getCurrentTopFragment(getFragmentManager());

                if (topFrag != null) {
                    if (topFrag instanceof YourFragment) {
                        //This fragment is being shown. 
                    } else {
                        //Navigating away from this fragment. 
                    }
                }
            }
        }
    });

এবং 'গেটকন্টরটপফ্রেগমেন্ট' পদ্ধতি:

public static Fragment getCurrentTopFragment(FragmentManager fm) {
    int stackCount = fm.getBackStackEntryCount();

    if (stackCount > 0) {
        FragmentManager.BackStackEntry backEntry = fm.getBackStackEntryAt(stackCount-1);
        return  fm.findFragmentByTag(backEntry.getName());
    } else {
        List<Fragment> fragments = fm.getFragments();
        if (fragments != null && fragments.size()>0) {
            for (Fragment f: fragments) {
                if (f != null && !f.isHidden()) {
                    return f;
                }
            }
        }
    }
    return null;
}

9

আপনি যদি সত্যিই অন্য খণ্ডের ভিতরে টুকরো প্রতিস্থাপন করতে চান তবে আপনার নেস্টেড টুকরা ব্যবহার করা উচিত

আপনার কোডে আপনার প্রতিস্থাপন করা উচিত

final FragmentManager mFragmentmanager =  getFragmentManager();

সঙ্গে

final FragmentManager mFragmentmanager =  getChildFragmentManager();

5
getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            List<Fragment> fragments = getFragmentManager().getFragments();
            if (fragments.size() > 0 && fragments.get(fragments.size() - 1) instanceof YoureFragment){
                //todo if fragment visible
            } else {
                //todo if fragment invisible
            }

        }
    });

তবে একাধিক টুকরো দৃশ্যমান হলে সাবধান হন


ধন্যবাদ, এটি কাজ করে, তবে কেবলমাত্র যদি একটি খণ্ড দৃশ্যমান হয় (সুতরাং, ViewPagerটুকরো টুকরো টুকরো টুকরো টুকরো টুকরো টুকরো করলে)।
কুলমাইন্ড

3

আমার একটি কোড আপনার সাথে খুব সমান এবং এটি যদি পজ () এবং onResume () এ কাজ করে। খণ্ড পরিবর্তন করার সময়, এই ফাংশনগুলি যথাক্রমে সক্রিয় হয়।

খণ্ডে কোড:

 @Override
public void onResume() {
    super.onResume();
    sensorManager.registerListener(this, proximidad, SensorManager.SENSOR_DELAY_NORMAL);
    sensorManager.registerListener(this, brillo, SensorManager.SENSOR_DELAY_NORMAL);
    Log.e("Frontales","resume");
}

@Override
public void onPause() {
    super.onPause();
    sensorManager.unregisterListener(this);
    Log.e("Frontales","Pause");

}

খণ্ডের পরিবর্তন হলে লগ করুন:

05-19 22:28:54.284 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:28:57.002 2371-2371/madi.cajaherramientas E/Frontales: Pause
05-19 22:28:58.697 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:29:00.840 2371-2371/madi.cajaherramientas E/Frontales: Pause
05-19 22:29:02.248 2371-2371/madi.cajaherramientas E/Frontales: resume
05-19 22:29:03.718 2371-2371/madi.cajaherramientas E/Frontales: Pause

ক্রেট ভিউ: খণ্ড

View rootView;
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    rootView = inflater.inflate(R.layout.activity_proximidad, container, false);
    ButterKnife.bind(this,rootView);
    inflar();
    setTextos();
    return rootView;
}

আমি যখন পিছনে পালস করব (ক্রিয়াকলাপে যেখানে আমি খণ্ডটি লোড করি):

@Override
public void onBackPressed() {

    int count = getFragmentManager().getBackStackEntryCount();

    if (count == 0) {
        super.onBackPressed();

    } else {
        getFragmentManager().popBackStack();
    }

 }

2

শিশু খণ্ডে আমি কী করি:

@Override
public void onDetach() {
   super.onDetach();
   ParentFragment pf = (ParentFragment) this.getParentFragment();
   pf.onResume();
}

এবং তারপরে প্যারেন্টফ্র্যাগমেন্টের উপর পুনরায় পোস্ট করুন r


1
আপনার কখনই জীবনচক্রের পদ্ধতিগুলিকে ম্যানুয়ালি কল করা উচিত নয়, বিশেষত একে অপরের অভ্যন্তরে
10-28

@ ব্রেকলাইন এই কৌশলটি কাজ করে। আপনার কি অন্য কোনও উপায় আছে?
বিকাশ পরজুলি

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

1

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

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


হ্যাঁ তারা একটি খণ্ডন কার্যকলাপের ভিতরে।
কৃষ্ণভদ্র

যদি টুকরোগুলি গতিশীলভাবে যুক্ত করা হয় তবে আপনি যতগুলি খণ্ড করতে চান তেমন যোগ করতে পারেন তবে এক্সএমএল <ফ্রেগমেন্ট> ট্যাগে সংজ্ঞায়িত সংখ্যায় নয়
অবৈধ যুক্তি

1

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

মিডল_ফ্র্যাগমেন্টটি ফ্রেমলআউটে পরিণত করুন, এবং নীচের মতো এটিকে লোড করুন এবং আপনার ইভেন্টগুলি আগুন জ্বলবে।

getFragmentManager().beginTransation().
    add(R.id.middle_fragment, new MiddleFragment()).commit();

1

আপনি এটি চেষ্টা করতে পারেন,

পদক্ষেপ 1: আপনার ক্রিয়াকলাপে ট্যাবসलेक्ट করা পদ্ধতি ওভাররাইড করুন

@Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
    // When the given tab is selected, switch to the corresponding page in
    // the ViewPager.
    try {
    if(MyEventsFragment!=null && tab.getPosition()==3)
    {
        MyEvents.fragmentChanged();
    }
    }
    catch (Exception e)
    {

    }
    mViewPager.setCurrentItem(tab.getPosition());
}

পদক্ষেপ 2: স্থির পদ্ধতি ব্যবহার করে আপনি আপনার খণ্ডে যা চান তা করতে পারেন,

public static void fragmentChanged()
{
    Toast.makeText(actvity, "Fragment Changed", Toast.LENGTH_SHORT).show();
}

1

আমি আমার ক্রিয়াকলাপে - কোটলিন ব্যবহার করি

supportFragmentManager.addOnBackStackChangedListener {
                val f = supportFragmentManager.findFragmentById(R.id.fragment_container)

                if (f?.tag == "MyFragment")
                {
                    //doSomething
                }
            }

0

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


0

onPause() পদ্ধতিটি আপনি ব্যবহার করতে পারেন এমন ক্রিয়াকলাপ শ্রেণিতে কাজ করে:

public void onDestroyView(){
super.onDestroyView    
}

একই উদ্দেশ্যে ..


0

নীচের পদক্ষেপগুলি অনুসরণ করুন, এবং আপনি প্রয়োজনীয় উত্তর পাবেন

1- উভয় টুকরা জন্য, একটি নতুন বিমূর্ত পিতা বা মাতা তৈরি করুন।
2- একটি কাস্টম বিমূর্ত পদ্ধতি যুক্ত করুন যা তাদের উভয় দ্বারা প্রয়োগ করা উচিত।
3- দ্বিতীয়টির সাথে প্রতিস্থাপন করার আগে এটি বর্তমান উদাহরণ থেকে কল করুন।


কোনও ব্যবহারকারী টুকরোগুলি 2 থেকে টুকরো 1 এ ফিরে আসার ক্ষেত্রে এটি কীভাবে সহায়তা করবে?
শীতলমান্ড

0

@ গর এর উত্তরের ভিত্তিতে আমি কোটলিনেও একই রকম লিখেছি। onCreate()কোনও ক্রিয়াকলাপের মধ্যে এই কোডটি রাখুন । এটি দৃশ্যমান এক টুকরা জন্য কাজ করে। আপনার যদি ViewPagerটুকরো টুকরো থাকে তবে এটি ViewPagerপূর্বের নয়, এর টুকরো কল করবে ।

supportFragmentManager.addOnBackStackChangedListener {
    supportFragmentManager.fragments.lastOrNull()?.onResume()
}

পড়ার পর https://medium.com/@elye.project/puzzle-fragment-stack-pop-cause-issue-on-toolbar-8b947c5c07c6 আমি বুঝলাম যে এটা দিয়ে নতুন টুকরা সংযুক্ত করতে অনেক পরিস্থিতিতে ভাল হবে replaceনা add। সুতরাং onResumeকিছু ক্ষেত্রে একটি প্রয়োজন অদৃশ্য হয়ে যাবে।


0

কল করা হচ্ছে ft.replace অনপস (প্রতিস্থাপিত টুকরাটির) এবং অনরেসিউম (প্রতিস্থাপনের খণ্ডটির) ট্রিগার করা উচিত।

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


এটি কোনও উত্তর নয়, কারও ডিজাইনের জন্য "অ্যাড" করা আবশ্যক কি ?!
ফরিদ

0

যদিও বিভিন্ন কোড সহ, আমি ওপি হিসাবে একই সমস্যাটি পেয়েছি, কারণ আমি মূলত ব্যবহার করেছি

fm.beginTransaction()
            .add(R.id.fragment_container_main, fragment)
            .addToBackStack(null)
            .commit();

পরিবর্তে

fm.beginTransaction()
                .replace(R.id.fragment_container_main, fragment)
                .addToBackStack(null)
                .commit();

"প্রতিস্থাপন" দিয়ে আপনি দ্বিতীয় খণ্ডটি থেকে ফিরে আসার সাথে সাথে প্রথম খণ্ডটি পুনরায় তৈরি করা হয় এবং সেইজন্য onResume () নামেও ডাকা হয়।


এটি কোনও উত্তর নয়, কারও ডিজাইনের জন্য "অ্যাড" করা আবশ্যক কি ?!
ফরিদ

-2

একটি খণ্ড লেনদেন তৈরি করার সময়, নিম্নলিখিত কোডটি যুক্ত করার বিষয়টি নিশ্চিত করুন।

// Replace whatever is in the fragment_container view with this fragment, 
// and add the transaction to the back stack 
transaction.replace(R.id.fragment_container, newFragment); 
transaction.addToBackStack(null); 

এছাড়াও নিশ্চিত হয়ে নিন, লেনদেনটিকে ব্যাকস্ট্যাকে যুক্ত করার পরে প্রতিশ্রুতিবদ্ধ হওয়া

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