हमें वास्तव में उसी व्यवहार को लागू करना था जिसे आप हाल ही में किसी एप्लिकेशन के लिए वर्णन करते हैं। स्क्रीन और एप्लिकेशन के समग्र प्रवाह को पहले से ही परिभाषित किया गया था इसलिए हमें इसके साथ रहना पड़ा (यह एक आईओएस ऐप क्लोन है ...)। सौभाग्य से, हम ऑन-स्क्रीन बैक बटन से छुटकारा पाने में कामयाब रहे :)
हमने TabActivity, FragmentActivities (हम टुकड़े के लिए समर्थन पुस्तकालय का उपयोग कर रहे थे) और Fragments के मिश्रण का उपयोग करके समाधान को हैक किया। पूर्वव्यापी में, मुझे पूरा यकीन है कि यह सबसे अच्छा वास्तुकला निर्णय नहीं था, लेकिन हम काम करने में सफल रहे। अगर मुझे इसे फिर से करना पड़ा, तो मैं शायद एक और गतिविधि-आधारित समाधान (कोई टुकड़े नहीं) करने की कोशिश करूंगा, या कोशिश करूंगा और टैब के लिए केवल एक ही गतिविधि होगी और बाकी सभी दृश्यों को देखने दूंगा (जो मुझे लगता है कि बहुत अधिक हैं समग्र गतिविधियों की तुलना में पुन: प्रयोज्य)।
इसलिए आवश्यकताएं प्रत्येक टैब में कुछ टैब और नेस्टेबल स्क्रीन रखने की थीं:
tab 1
screen 1 -> screen 2 -> screen 3
tab 2
screen 4
tab 3
screen 5 -> 6
आदि...
तो कहते हैं: उपयोगकर्ता टैब 1 में शुरू होता है, स्क्रीन 1 से स्क्रीन 2 तक फिर स्क्रीन 3 पर नेविगेट करता है, वह तब टैब 3 पर स्विच करता है और स्क्रीन 4 से 6 तक नेविगेट करता है; यदि टैब 1 पर वापस स्विच किया जाता है, तो उसे स्क्रीन 3 को फिर से देखना चाहिए और यदि उसने वापस दबाया तो उसे स्क्रीन 2 पर वापस आना चाहिए; वापस फिर से और वह स्क्रीन 1 में है; टैब 3 पर जाएँ और वह फिर से स्क्रीन 6 में है।
आवेदन में मुख्य गतिविधि MainTabActivity है, जो TabActivity का विस्तार करती है। प्रत्येक टैब एक गतिविधि के साथ जुड़ा हुआ है, बताएं ActivateTab1, 2 और 3. और फिर प्रत्येक स्क्रीन एक टुकड़ा होगा:
MainTabActivity
ActivityInTab1
Fragment1 -> Fragment2 -> Fragment3
ActivityInTab2
Fragment4
ActivityInTab3
Fragment5 -> Fragment6
प्रत्येक गतिविधिइनटैब एक समय में केवल एक ही टुकड़ा रखता है, और जानता है कि एक टुकड़े को दूसरे एक के लिए कैसे बदलना है (एक एक्टविटीग्रुप के समान ही)। अच्छी बात यह है कि इस तरह से प्रत्येक टैब के लिए अलग-अलग बैक स्टैक को मंटेन करना काफी आसान है।
प्रत्येक एक्टिविटी इनटैब के लिए कार्यक्षमता काफी समान थी: पता है कि एक टुकड़े से दूसरे में कैसे नेविगेट करें और एक बैक स्टैक बनाए रखें, इसलिए हमने इसे बेस क्लास में रखा। आइए इसे सिर्फ़ एक्टिविटीइनटैब कहें:
abstract class ActivityInTab extends FragmentActivity { // FragmentActivity is just Activity for the support library.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_in_tab);
}
/**
* Navigates to a new fragment, which is added in the fragment container
* view.
*
* @param newFragment
*/
protected void navigateTo(Fragment newFragment) {
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, newFragment);
// Add this transaction to the back stack, so when the user presses back,
// it rollbacks.
ft.addToBackStack(null);
ft.commit();
}
}
Activity_in_tab.xml सिर्फ यह है:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:isScrollContainer="true">
</RelativeLayout>
जैसा कि आप देख सकते हैं, प्रत्येक टैब के लिए दृश्य लेआउट समान था। ऐसा इसलिए है क्योंकि यह केवल एक फ्रेम-आउट नामक सामग्री है जो प्रत्येक टुकड़े को धारण करेगी। अंश वे होते हैं जिनमें प्रत्येक स्क्रीन का दृश्य होता है।
बस बोनस अंक के लिए, हमने उपयोगकर्ता को वापस दबाए जाने पर एक पुष्टिकरण संवाद दिखाने के लिए कुछ छोटे कोड भी जोड़े हैं और वापस जाने के लिए अधिक टुकड़े नहीं हैं:
// In ActivityInTab.java...
@Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
if (manager.getBackStackEntryCount() > 0) {
// If there are back-stack entries, leave the FragmentActivity
// implementation take care of them.
super.onBackPressed();
} else {
// Otherwise, ask user if he wants to leave :)
showExitDialog();
}
}
यह बहुत ज्यादा सेटअप है। जैसा कि आप देख सकते हैं, प्रत्येक FragmentActivity (या बस Android में गतिविधि> 3) सभी बैक-स्टैकिंग का ख्याल रख रही है, जिसके साथ वह खुद FragmentManager है।
ActivityInTab1 जैसी गतिविधि वास्तव में सरल होगी, यह सिर्फ यह दिखाएगा कि यह पहला टुकड़ा है (यानी स्क्रीन):
public class ActivityInTab1 extends ActivityInTab {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
navigateTo(new Fragment1());
}
}
फिर, अगर एक टुकड़े को दूसरे टुकड़े में नेविगेट करने की आवश्यकता होती है, तो उसे थोड़ा बुरा कास्टिंग करना पड़ता है ... लेकिन यह उतना बुरा नहीं है:
// In Fragment1.java for example...
// Need to navigate to Fragment2.
((ActivityIntab) getActivity()).navigateTo(new Fragment2());
तो यह बहुत सुंदर है। मुझे पूरा यकीन है कि यह एक बहुत ही विहित नहीं है (और ज्यादातर निश्चित रूप से बहुत अच्छा नहीं) समाधान है, इसलिए मैं अनुभवी एंड्रॉइड डेवलपर्स से पूछना चाहता हूं कि इस कार्यक्षमता को प्राप्त करने के लिए एक बेहतर दृष्टिकोण क्या होगा, और यदि यह "यह कैसे नहीं है" किया "एंड्रॉयड में, मैं अगर तुम मुझे कुछ लिंक या सामग्री बताते हैं कि जो है को इंगित कर सकता है कि सराहना करेंगे इस (टैब, टैब में नेस्टेड स्क्रीन, आदि) के पास जाने एंड्रॉयड रास्ता। टिप्पणी में इस जवाब को अलग करने के लिए स्वतंत्र महसूस करें :)
एक संकेत के रूप में कि यह समाधान बहुत अच्छा नहीं है, हाल ही में मुझे कुछ नेविगेशन कार्यक्षमता को एप्लिकेशन में जोड़ना था। कुछ विचित्र बटन जो उपयोगकर्ता को एक टैब से दूसरे और नेस्टेड स्क्रीन में ले जाने चाहिए। उस प्रोग्राम को करना बट में एक दर्द था, क्योंकि कौन जानता है-कौन-कौन समस्याएँ हैं और इनसे निपटना कब टुकड़े और गतिविधियाँ वास्तव में तुरंत और आरंभिक हैं। मुझे लगता है कि यह बहुत आसान होता अगर उन स्क्रीन और टैब में सिर्फ व्यू होते।
अंत में, यदि आपको अभिविन्यास परिवर्तन से बचने की आवश्यकता है, तो यह महत्वपूर्ण है कि आपके टुकड़े setArguments / getArguments का उपयोग करके बनाए जाते हैं। यदि आप अपने टुकड़ों के कंस्ट्रक्टर्स में इंस्टेंस वेरिएबल सेट करते हैं तो आप खराब हो जाएंगे। लेकिन सौभाग्य से यह वास्तव में ठीक करना आसान है: बस निर्माता में सेटआर्गुमेंट्स में सब कुछ बचाएं और फिर उन चीजों को पुनः प्राप्त करें जिनके साथ onAreate का उपयोग करें।