2012-10-26 21 views
68

मैं तीन टैब के साथ एक टैब किए Actionbar/viewpager लेआउट के साथ नेविगेशन ActionBar कहना एक, बी, और सी। टैब सी टैब (खंड) में, मैं एक और टुकड़ा जोड़ रहा हूं, खंड डी कहता है।टुकड़े

DFragment f= new DFragment(); 
ft.add(android.R.id.content, f, ""); 
ft.remove(CFragment.this); 
ft.addToBackStack(null); 
ft.commit(); 

साथ मैं बटन को जोड़ने के लिए DFragment के onResume में ActionBar संशोधित: DFragment में अब

ActionBar ab = getActivity().getActionBar(); 
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD); 
ab.setDisplayHomeAsUpEnabled(true); 
ab.setDisplayShowHomeEnabled(true); 

, जब मैं हार्डवेयर (फोन) वापस जाएं बटन दबाएं, मैं मूल टैब्ड (एबीसी) लेआउट पर लौटने CFragment चयनित के साथ। मैं एक्शनबार अप बटन के साथ इस कार्यक्षमता को कैसे प्राप्त कर सकता हूं?

+0

संभावित डुप्लिकेट ([? टुकड़े में onBackPressed() कैसे लागू करें] http://stackoverflow.com/questions/5448653/how-to-implement-onbackpressed-in-fragments) –

उत्तर

157

OnBackStackChangedListener लागू करें और इस कोड को अपनी फ्रैगमेंट गतिविधि में जोड़ें।

@Override 
public void onCreate(Bundle savedInstanceState) { 
    //Listen for changes in the back stack 
    getSupportFragmentManager().addOnBackStackChangedListener(this); 
    //Handle when activity is recreated like on orientation Change 
    shouldDisplayHomeUp(); 
} 

@Override 
public void onBackStackChanged() { 
    shouldDisplayHomeUp(); 
} 

public void shouldDisplayHomeUp(){ 
    //Enable Up button only if there are entries in the back stack 
    boolean canback = getSupportFragmentManager().getBackStackEntryCount()>0; 
    getSupportActionBar().setDisplayHomeAsUpEnabled(canback); 
} 

@Override 
public boolean onSupportNavigateUp() { 
    //This method is called when the up button is pressed. Just the pop back stack. 
    getSupportFragmentManager().popBackStack(); 
    return true; 
} 
+16

'ऑनसपोर्टनेटविगअप()' के बारे में, "विधि अपने सुपरक्लास से विधि को ओवरराइड नहीं करता है"। – Fred

+0

यह उत्तर स्वीकृत उत्तर से अधिक उपयोगी है। बहुत बहुत धन्यवाद। – tinker

+0

धन्यवाद, सोहेलएज़िज के जवाब से यह आसान और साफ है! – javaxian

34

मुझे मिल गया। ऑप्शन इटैम पर ओवरराइड करें होस्टिंग गतिविधि में और बैकस्टैक पॉपअप करें, उदा।

public boolean onOptionsItemSelected(MenuItem item) { 

    switch (item.getItemId()) { 
    case android.R.id.home: 
    FragmentManager fm = getSupportFragmentManager(); 
    if (fm.getBackStackEntryCount() > 0) { 
      fm.popBackStack(); 
     } 
     return true; 
    default: 
     return super.onOptionsItemSelected(item);; 
    } 
} 

कॉल getActionBar().setDisplayHomeAsUpEnabled(boolean); और getActionBar().setHomeButtonEnabled(boolean);onBackStackChanged() में नीचे के रूप में एक जवाब में विस्तार से बताया।

+3

आपको getActivity() प्राप्त करना होगा। GetActionBar()। SetDisplayHomeAsUpEnabled (false); एक बार जब आप बैक स्टैक पॉप करते हैं तो ऊपर बटन को निकालने के लिए – JoP

+0

यह करने का यह सही तरीका नहीं है। यह ऊपर बटन सक्षम रहता है। –

+1

आपको उस कोड को 'switch' कथन के अंदर' android.R.id.home' के साथ रखना चाहिए। – Fred

18

आप एक माता पिता गतिविधि है और इस बटन एक वापस बटन के रूप में काम करना चाहते हैं, तो आप इस कोड का उपयोग कर सकते हैं:

अपने मुख्य गतिविधि कक्षा में onCreate में जोड़ना

getSupportFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 
     @Override 
     public void onBackStackChanged() { 
      int stackHeight = getSupportFragmentManager().getBackStackEntryCount(); 
      if (stackHeight > 0) { // if we have something on the stack (doesn't include the current shown fragment) 
       getSupportActionBar().setHomeButtonEnabled(true); 
       getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
      } else { 
       getSupportActionBar().setDisplayHomeAsUpEnabled(false); 
       getSupportActionBar().setHomeButtonEnabled(false); 
      } 
     } 

    }); 

और उसके बाद तो जैसे onOptionsItemSelected जोड़ें:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      getSupportFragmentManager().popBackStack(); 
      return true; 
    .... 
} 

मैं आम तौर पर उपयोग करने के यह सब समय और लगता है सुंदर कानूनी

+1

मैंने इस कोड का उपयोग ठीक से 'गतिविधि' में करने की कोशिश की, उम्मीद है कि यह उस खंड से वापस आ जाएगा जो उसने शुरू किया था। जब मैं अपनी 'गतिविधि' पर जाता हूं, तो बैक बटन मेरे ऐप आइकन के पास दिखाई देता है, लेकिन मैं आइकन पर क्लिक करता हूं और कुछ भी नहीं होता है (इसे वापस टुकड़े पर जाना चाहिए)। कोई विचार क्यों? धन्यवाद। – Azurespot

+1

@Daniel आपका कोड वैध है .. यह काम करता है। आप बस इसे पकड़ने के विकल्प के साथ घूमना चाहते हैं .. आप किसी भी अप्रत्याशित अपवाद और ऐप्स को – Olu

+1

@NoniA को क्रैश करने से रोकने के लिए जानते हैं। यह केवल पिछले खंड (उदाहरण के लिए, खंड बी -> खंड ए) पर वापस जा रहा है, यदि आप एक नई गतिविधि में 1 खंड को बढ़ा रहे हैं, तो यह पूर्व गतिविधि पर वापस नहीं जायेगा। –

2

यह एक बहुत ही अच्छा और विश्वसनीय समाधान है: http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/

पुरुष एक सार टुकड़ा है कि backPress व्यवहार संभालती है और रणनीति पद्धति का उपयोग कर सक्रिय टुकड़े के बीच स्विच कर रहा है बना दिया है।

आप में से कुछ वहाँ हो सकता है सार वर्ग में एक छोटे से दोष के लिए ...

शीघ्र ही, लिंक से समाधान इस प्रकार है:

// Abstract Fragment handling the back presses 

public abstract class BackHandledFragment extends Fragment { 
    protected BackHandlerInterface backHandlerInterface; 
    public abstract String getTagText(); 
    public abstract boolean onBackPressed(); 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     if(!(getActivity() instanceof BackHandlerInterface)) { 
      throw new ClassCastException("Hosting activity must implement BackHandlerInterface"); 
     } else { 
      backHandlerInterface = (BackHandlerInterface) getActivity(); 
     } 
    } 

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

     // Mark this fragment as the selected Fragment. 
     backHandlerInterface.setSelectedFragment(this); 
    } 

    public interface BackHandlerInterface { 
     public void setSelectedFragment(BackHandledFragment backHandledFragment); 
    } 
} 

और गतिविधि में उपयोग:

// BASIC ACTIVITY CODE THAT LETS ITS FRAGMENT UTILIZE onBackPress EVENTS 
// IN AN ADAPTIVE AND ORGANIZED PATTERN USING BackHandledFragment 

public class TheActivity extends FragmentActivity implements BackHandlerInterface { 
    private BackHandledFragment selectedFragment; 

    @Override 
    public void onBackPressed() { 
     if(selectedFragment == null || !selectedFragment.onBackPressed()) { 
      // Selected fragment did not consume the back press event. 
      super.onBackPressed(); 
     } 
    } 

    @Override 
    public void setSelectedFragment(BackHandledFragment selectedFragment) { 
     this.selectedFragment = selectedFragment; 
    } 
} 
+0

हालांकि यह लिंक प्रश्न का उत्तर दे सकता है, जवाब के आवश्यक हिस्सों [यहां] (http://meta.stackoverflow.com/a/8259) को शामिल करना बेहतर है और संदर्भ के लिए लिंक प्रदान करना बेहतर है। लिंक किए गए पृष्ठ में परिवर्तन होने पर लिंक-केवल उत्तर अमान्य हो सकते हैं। – bummi

+0

ठीक है, मैं इसे देख लूंगा। धन्यवाद। – zatziky

+0

बीटीडब्ल्यू: यदि आप डुप्लिकेट की पहचान करते हैं, तो कृपया उन्हें ध्वजांकित करें। धन्यवाद। – bummi

9

आप वापस बटन जैसे बटन के साथ वापस जा सकते हैं;

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      super.onBackPressed(); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 
+0

सरल और उपयोगी – eren130

4

मैं Roger Garzon Nieto's और sohailaziz's जवाब का एक संयोजन का इस्तेमाल किया। मेरे ऐप में एक एकल मुख्य गतिविधि है, और इसमें ए, बी, सी टुकड़े हैं जो इसमें लोड होते हैं। मेरा "घर" खंड (ए) OnBackStackChangedListener लागू करता है, और बैकस्टैक के आकार की जांच करता है; यदि यह एक से कम है, तो यह यूपी बटन छुपाता है।टुकड़े बी और सी हमेशा बैक बटन लोड करते हैं (मेरे डिजाइन में, बी ए से लॉन्च किया जाता है, और सी बी से लॉन्च किया जाता है)। MainActivity ही सिर्फ उत्तर प्रदेश बटन नल पर backstack दिखाई दे, और तरीकों को दिखाने के लिए/बटन, जो टुकड़े फोन को छिपाने के होते हैं:

MainActivity:

public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     // Respond to the action bar's Up/Home button 
     case android.R.id.home: 
      getSupportFragmentManager().popBackStack(); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

public void showUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(true); } 
public void hideUpButton() { getSupportActionBar().setDisplayHomeAsUpEnabled(false); } 

fragmentA (लागू करता FragmentManager.OnBackStackChangedListener) :

public void onCreate(Bundle savedinstanceSate) { 
    // listen to backstack changes 
    getActivity().getSupportFragmentManager().addOnBackStackChangedListener(this); 

    // other fragment init stuff 
    ... 
} 

public void onBackStackChanged() { 
    // enable Up button only if there are entries on the backstack 
    if(getActivity().getSupportFragmentManager().getBackStackEntryCount() < 1) { 
     ((MainActivity)getActivity()).hideUpButton(); 
    } 
} 

fragmentB, fragmentC:

public void onCreate(Bundle savedinstanceSate) { 
    // show the UP button 
    ((MainActivity)getActivity()).showUpButton(); 

    // other fragment init stuff 
    ... 
} 
5

मुझे पता है कि यह प्रश्न पुराना है, लेकिन हो सकता है कि कोई (मेरे जैसा) भी इसकी आवश्यकता हो।

अपनी गतिविधि AppCompatActivity फैली हैं, तो आप एक सरल (दो कदम) समाधान का उपयोग कर सकते हैं:

1 - जब भी आप एक गैर घर टुकड़ा जोड़ने सिर्फ सही टुकड़ा लेन-देन करने से बाद बटन दिखाने के लिए, । इस तरह:

// ... add a fragment 
    // Commit the transaction 
    transaction.commit(); 

    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

2 - फिर जब यूपी बटन दबाया जाता है, तो आप इसे छुपाते हैं।

@Override 
public boolean onSupportNavigateUp() { 
    getSupportActionBar().setDisplayHomeAsUpEnabled(false);   
    return true; 
} 

यही है।

2

यह मेरे लिए काम किया। समर्थन पर ओवरराइड करेंविगेटअप और ऑन बैकप्रेस, उदाहरण के लिए (कोटलिन में कोड);

override fun onBackPressed() { 
    val count = supportFragmentManager.backStackEntryCount 
    if (count == 0) { 
     super.onBackPressed() 
    } else { 
     supportFragmentManager.popBackStack() 
    } 
} 

override fun onSupportNavigateUp(): Boolean { 
    super.onSupportNavigateUp() 
    onBackPressed() 
    return true 
} 

अब टुकड़ा में, आप प्रदर्शित करता है, तो ऊपर तीर

activity.supportActionBar?.setDisplayHomeAsUpEnabled(true) 

क्लिक करने से यह आप वापस पिछले गतिविधि पकड़ता पर।

0

Kotlin:

class MyActivity : AppCompatActivity() { 

    override fun onCreate(savedInstanceState: Bundle?) { 
     ... 
     supportFragmentManager.addOnBackStackChangedListener { setupHomeAsUp() } 
     setupHomeAsUp() 
    } 

    private fun setupHomeAsUp() { 
     val shouldShow = 0 < supportFragmentManager.backStackEntryCount 
     supportActionBar?.setDisplayHomeAsUpEnabled(shouldShow) 
    } 

    override fun onSupportNavigateUp(): Boolean = 
     supportFragmentManager.popBackStack().run { true } 

    ... 
} 
की
संबंधित मुद्दे