विखंडन जीवनचक्र - किस विधि को दिखाने / छिपाने पर कहा जाता है?


99

मैं उन्हें दिखा / छिपाकर, Fragments (मेरे नेविगेशनड्रावर में) के बीच स्विच करने के लिए निम्न विधि का उपयोग कर रहा हूं।

protected void showFragment(int container, Fragment fragment, String tag, String lastTag, boolean addToBackStack ) {

        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();

        if ( lastTag != null && !lastTag.equals("")) {
            Fragment lastFragment = fragmentManager.findFragmentByTag( lastTag );
            if ( lastFragment != null ) {
                transaction.hide( lastFragment );
            }
        }

        if ( fragment.isAdded() ) {
            transaction.show( fragment );
        }
        else {
            transaction.add( container, fragment, tag );
        }

        if ( addToBackStack ) {
            transaction.addToBackStack( tag );
        }

        transaction.commit();

        // set the active tag
        activeFragTag = tag;
    }

जब मैं इस बारे में स्पष्ट नहीं होता हूं कि जब मैं इसे दिखाता हूं या छिपाता हूं तो फ्रैगमेंट्स जीवनचक्र की किस विधि को कहा जाता है? (चूँकि वहाँ कोई विधि नहीं है जैसे onShow () या onHide () im यकीन नहीं है कि क्या उपयोग करना है)। मैं एक निश्चित फ्रैगमेंट को दिखाने और छिपाने पर विशिष्ट क्रियाएं करना चाहता हूं।


जब आप Fragment.show () को कॉल करते हैं, तो कुछ समय बाद, टुकड़ा ट्रिगर होता है onCreate(), उसके onCreateDialog()बादonCreateView()
किसी ने कहीं

जवाबों:


122

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

आपके लेआउट के आधार पर Android onStart()तब भी कॉल कर सकता है, जब आपका Fragment अभी तक दिखाई नहीं दे रहा है, लेकिन यह एक दृश्यमान पैरेंट कंटेनर से संबंधित है। उदाहरण के लिए, यह मान्य है android.support.v4.view.ViewPagerजिसके लिए आपको Fragment.setUserVisibleHint()विधि को ओवरराइड करने की आवश्यकता होती है । किसी भी मामले में, यदि आपको ब्रॉडकास्टरेसीवर्स या अन्य श्रोताओं को पंजीकृत / अपंजीकृत करने की आवश्यकता है, तो आप सुरक्षित रूप से उपयोग कर सकते हैं onStart()और onStop()विधियाँ क्योंकि उन्हें हमेशा कहा जाएगा।

नोट: कुछ खंड कंटेनर अदृश्य टुकड़े शुरू कर सकते हैं। इस स्थिति को संभालने के लिए आप ओवरराइड कर सकते हैं Fragment.onHiddenChanged(boolean hidden)प्रलेखन के अनुसार , एक टुकड़ा उपयोगकर्ता के लिए दृश्यमान होने के लिए प्रारंभ और दृश्य (छिपा हुआ नहीं) होना चाहिए।

अद्यतन: यदि आप उपयोग करते हैं android.support.v4.widget.DrawerLayoutतो दराज के नीचे एक टुकड़ा शुरू हो जाता है और दराज खुला होने पर भी दिखाई देता है। इस मामले में आप प्रयोग करने की आवश्यकता है DrawerLayout.setDrawerListener()और के लिए सुनने onDrawerClosed()और onDrawerOpened()कॉलबैक।


14
onStopऔर onPauseतब नहीं कहा जाता है जब एक लेनदेन का उपयोग करके एक टुकड़ा अदृश्य हो जाता है। फिर भी onHiddenChangedइसे s1rius उत्तर के रूप में कहा जाता है
Yoann Hercouet

यह नेवीगेशनड्रॉलर में काम नहीं करता है। onHiddenChanged को v4 / v11 समर्थन परिवाद पर नहीं कहा जाता है। onStart और onResume को हर बार नहीं बुलाया जाएगा, जब दराज का लेआउट खुलता है।
drdrej

@drdrej समस्या यह है कि दराज पूरी तरह से नीचे कोई छिपाना नहीं है। यदि आप समर्थन लाइब्रेरी से ड्रालेरआउट का उपयोग करते हैं, तो आपको ड्रालेरिस्टनर का उपयोग करने की आवश्यकता है।
सर्ज शफरेंका

69

मैं @ इस विधि को लागू करता हूं और अपनी समस्या का समाधान करता हूं:

@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
        //do when hidden
    } else {
       //do when show
    }
}

1
बिना किसी समाधान के प्रयास किया, लेकिन setUserVisibleHintजैसा कि stackoverflow.com/a/18375436/1815624 वर्क्स में दिखाया गया है
CrandellWS

36

निश्चित रूप से आप ऐसा करने के लिए निम्न विधि से @ हटा सकते हैं:

@Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isVisibleToUser) {
            // Do your Work
        } else {
            // Do your Work
        }
    }

और एक आसानी से पता चल सकता है कि टुकड़ा उपयोगकर्ता को दिखाई दे रहा है या नहींgetUserVisibleHint()
ARIF

2
setUserVanishHint व्यू पेजर के साथ काम करता है लेकिन नियमित रूप से टुकड़े करने वाले कंटेनर के साथ नहीं।
22

इस समस्या को हल करता है मेरी समस्या :)
RAJESH KUMAR ARUMUGAM

इसने मेरे लिए ViewPager पर काम किया। onHiddenChanged ने काम नहीं किया।
जीवित-प्रेम

मेरी समस्या का हल!
जद चहाइन

3

दृश्य टुकड़ा व्यवहार में टुकड़ा नियमित टुकड़ा कंटेनर के साथ अलग है।

इस कोड को आज़माएं:

    boolean mIsVisibleToUser;

    /**
     * is visible to user
     */
    public void show() {
        //do when show
    }

    /**
     * is invisible to user
     */
    public void hide() {
        //do when gone
    }

    @Override
    public void onResume() {
        super.onResume();
        if (!mIsVisibleToUser && getUserVisibleHint()) {
            mIsVisibleToUser = true;
            show();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mIsVisibleToUser && getUserVisibleHint()) {
            mIsVisibleToUser = false;
            hide();
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (isResumed()) {
            if (mIsVisibleToUser != isVisibleToUser) {
                mIsVisibleToUser = isVisibleToUser;
                if (isVisibleToUser) show();
                else hide();
            }
        }
    }

    public boolean isVisibleToUser() {
        return mIsVisibleToUser;
    }

2

इस कोड को आज़माएं:

@Override
public void setUserVisibleHint(boolean visible)
{
    super.setUserVisibleHint(visible);
    if (visible && isResumed())
    {
         onResume();
    }
}

@Override
public void onResume()
{
    super.onResume();
    if (!getUserVisibleHint())
    {
        return;
    }

    //Add your code this section
}

2

आप 'onCreateView' (या 'onActivityCreated') और 'onHiddenChanged' का उपयोग कर सकते हैं। पहले शो के लिए 'onCreateView' का उपयोग करें और बाद के लिए 'onHiddenChanged' का उपयोग करें। लेनदेन नियंत्रण पर 'setMenuVisibility' को नहीं कहा जाता है।

@Override
public View OnCreateView() {
   // fragment will show first
}

@Override
public void onHiddenChanged(boolean hidden) {
    if (!hidden) {
        // fragment will show 
    }
    else {
        // fragment will hide
    }
}

onHiddenChanged () को मेरे खंडन के साथ नहीं कहा जाता है
matdev

1

बस अपने setUserVanishHint में यह प्रयास करें ()

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser && getView() != null){
        isActive = true;
        init();
    }else if(isVisibleToUser && getView() == null){
        isActive = false;
    }else{
        isActive = true;
    }
}

और इस कोड को onCreateView () में बनाएँ :

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
  if(!isActive){
      init();
  }
}

isVisibleToUser && getView() != nullमेरे लिए एकदम सही काम किया!
बॉबी

1

टुकड़ा दिखाई देने पर विखंडन विधि को कॉल करने का एक और तरीका है और आप गतिविधि में व्यूपेजर का उपयोग करते हैं।

// सबसे पहले आप एक इंटरफ़ेस बनाएँ

public interface ShowFragmentVisible{
      public void showFragment();}

// उसके बाद यह इंटरफ़ेस फ्रैगमेंट की तरह लागू होता है

      public class MyFragment extends Fragment implements 
         ShowFragmentVisible {
            @Override
public void showFragment() {
}

// अब आपकी एक्टिविटी हो जाती है फिर इंटरफ़ेस का ऑब्जेक्ट बनाएं और जब addOnViewpagerListener को कॉल करें

   ShowFragmentVisible showFragmentVisible;

@Override
public void onAttachFragment(Fragment fragment) {
    super.onAttachFragment(fragment);

    if (fragment instanceof ShowFragmentVisible) {
        showFragmentVisible = (ShowFragmentVisible) fragment;
    }

}
     //your viewpager method
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            if (position==0){
                showFragmentVisible.showFragment();

           }

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });


this is another alternative,but its work for me successfully

0

setUserVisibleHintपहले फोन करो onCreateView। और आप किसी भी दृश्य को अंदर सेट नहीं कर सकते हैं setUserVigureHint I का उपयोग करें

public void setMenuVisibility(final boolean visible)

के लिए दृश्यता और onHiddenChanged () पहली बार के लिए फोन नहीं किया । जब छिपी हुई स्थिति बदलती है तो यह कॉल करता है। क्योंकि ए fragment is visible by default। इस विधि को प्राप्त करने के लिए पहली बार आपको कॉल mFragmentTransaction.hide(oldFragment)करना होगा तब यह काम करेगा

ध्यान दें

यदि आप setUserVoice संकेत का उपयोग करना चाहते हैं और इस पद्धति का उपयोग देखें अपडेट करें


0

बेशक आप ओवरराइड कर सकते हैं setUserVisibleHintया setMenuVisibilityअगर आपको एक्सेस करने की ज़रूरत है Contextया Activity, वे वहाँ शून्य होंगे! एक और तरीका है onStartजिसमें हमेशा हाथ में उपलब्ध संदर्भ होता है, लेकिन यह केवल एक बार खंड के निर्माण पर बुलाया जाएगा और यदि आप एक टुकड़े में अपने टुकड़े के बीच बढ़ना शुरू करते हैं, तो आप देखेंगे कि यह दूसरे दृश्य में नहीं मिलेगा और बाद में ।

तो अब क्या करना है?

वर्कअराउंड काफी आसान है, onStartपहली यात्रा के लिए और setMenuVisibilityबाद के लोगों के लिए उपयोग करें । आपका कोड शायद नीचे की तरह दिखेगा:

फ्रैगमेंट क्लास:

public class MyFragmentClass{
    private boolean isCurrentVisible = false;
...

@Override
public void onStart() {
    super.onStart();
    if (isCurrentVisible)
        doSth();
}

@Override
public void setMenuVisibility(boolean menuVisible){
    super.setMenuVisibility(menuVisible);
    this.isCurrentVisible = menuVisible;
    if(menuVisible && getContext() != null)
        doSth();
}

यह तरीका Contextहमेशा doSth()विधि के लिए उपलब्ध होगा ।


0

केवल यह मेरे लिए काम किया !! और setUserVisibleHint(...)अब हटा दिया गया है (मैं अंत में डॉक्स संलग्न करता हूं), जिसका अर्थ है कि कुछ अन्य उत्तर हटाए गए हैं;;

public class FragmentFirewall extends Fragment {
    /**
     * Required cause "setMenuVisibility(...)" is not guaranteed to be
     * called after "onResume()" and/or "onCreateView(...)" method.
     */
    protected void didVisibilityChange() {
        Activity activity = getActivity();
        if (isResumed() && isMenuVisible()) {
            // Once resumed and menu is visible, at last
            // our Fragment is really visible to user.
        }
    }

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

    @Override
    public void setMenuVisibility(boolean visible) {
        super.setMenuVisibility(visible);
        didVisibilityChange();
    }
}

परीक्षण किया और साथ NaviagationDrawerही साथ काम करता है , वहाँ isMenuVisible()हमेशा वापस आ जाएगा true(और onResume()पर्याप्त लगता है, लेकिन हम ViewPagerभी समर्थन करना चाहते हैं)।

setUserVisibleHintपदावनत किया गया है। यदि इस पद्धति को ओवरराइड किया जाता है, तो पास होने पर व्यवहार लागू किया trueजाना चाहिए Fragment.onResume(), और जब पास किया falseजाना चाहिए तो व्यवहार को लागू किया जाना चाहिए Fragment.onPause()

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