29

पर नेविगेट करना मुझे एक ऐसी गतिविधि मिली है जो प्रारंभ में एक ViewPager होस्ट करती है, जिसे FragmentPagerAdapter पर लगाया जाता है।Fragment के साथ ViewPager को प्रतिस्थापित करना - फिर

जब उपयोगकर्ता व्यूपैगर के बच्चे के टुकड़े के अंदर किसी आइटम पर क्लिक करता है, तो मैं एक नए फ्रेगमेंट के साथ एक खाली कंटेनर व्यू को प्रतिस्थापित करने के लिए एक फ्रैगमेंट ट्रांस्सेक्शन का उपयोग कर रहा हूं जिसे मैं नेविगेट करना चाहता हूं।

यदि मैं लेनदेन पर addToBackStack() का उपयोग करता हूं, लेनदेन करता हूं और फिर वापस नेविगेट करता हूं, तो मैं ViewPager के विचारों (प्रारंभिक लेआउट) पर वापस नहीं आ जाता हूं।

यदि मैं लेनदेन पर addToBackStack() का उपयोग नहीं करता हूं, तो लेनदेन करें और फिर वापस नेविगेट करें, एप्लिकेशन निकलता है।

ऐसा लगता है कि व्यूपेजर बैकस्टैक में नहीं जोड़ा गया है (जो आश्चर्यजनक नहीं है क्योंकि यह स्वयं में एक टुकड़ा नहीं है) .. लेकिन मुझे उम्मीद है कि डिफ़ॉल्ट व्यवहार यह होगा कि पिछली प्रेस मुझे वापस ले जाती है उन गतिविधियों के लिए प्रारंभिक दृश्य (ViewPager)।

जो मैंने पढ़ा है उसके आधार पर, ऐसा लगता है कि शायद एक टुकड़ा लेनदेन हो रहा है, व्यूपेजर या पेजर एडाप्टर का पता चलता है कि कौन सा टुकड़ा प्रदर्शन पर होना चाहिए।

मैं वास्तव में इसके साथ उलझन में हूं, लेकिन मैंने बैकप्रेस पर ओवरराइड करने और दर्शकों के दृश्यों को दिखाने और छिपाने के लिए कोड की एक बड़ी गड़बड़ी तैयार की। मैंने सोचा होगा कि उचित नेविगेशन करने के लिए डिफ़ॉल्ट व्यवहार का उपयोग करने का एक आसान तरीका है।

tl; डॉ

एक एक Viewpager होस्टिंग टुकड़े है। बी एक नया टुकड़ा है।

जब मैं ए के साथ ए को प्रतिस्थापित करता हूं, और फिर वापस दबाता हूं, तो मुझे ए पर वापस नेविगेट करने की उम्मीद है, लेकिन ऐसा नहीं हो रहा है।

कोई सलाह बहुत सराहना की जाएगी।

कोड:

MainActivity:

@Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 

     headingLayout = (RelativeLayout) findViewById(R.id.headingLayout); 
     headingLayout.setVisibility(View.GONE); 

     // Set up the ViewPager, attaching the adapter and setting up a listener 
     // for when the 
     // user swipes between sections. 
     mViewPager = (ViewPager) findViewById(R.id.pager); 

     mViewPager.setPageMargin(8); 

     /** Getting fragment manager */ 
     FragmentManager fm = getSupportFragmentManager(); 

     /** Instantiating FragmentPagerAdapter */ 
     MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm); 

     /** Setting the pagerAdapter to the pager object */ 
     mViewPager.setAdapter(pagerAdapter); 
. 
. 
. 
} 

    public void onListItemClicked(Fragment fragment) { 
     fromPlayer = false; 
     InitiateTransaction(fragment, true); 

    } 


    public void InitiateTransaction(Fragment fragment, boolean addToBackStack) { 

     invalidateOptionsMenu(); 

     FragmentManager fm = getSupportFragmentManager(); 
     FragmentTransaction ft = fm.beginTransaction(); 

     ft.replace(R.id.fragmentContainer, fragment).addToBackStack(null) 
       .commit(); 

    } 

PagerAdapter:

package another.music.player; 

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import another.music.player.fragments.AlbumListFragment; 
import another.music.player.fragments.ArtistListFragment; 
import another.music.player.fragments.SongListFragment; 

public class MyFragmentPagerAdapter extends FragmentPagerAdapter { 

    final int PAGE_COUNT = 3; 

    /** Constructor of the class */ 
    public MyFragmentPagerAdapter(FragmentManager fm) { 
     super(fm); 
    } 

    /** This method will be invoked when a page is requested to create */ 
    @Override 
    public Fragment getItem(int i) { 
     switch (i) { 
     case 0: 
      ArtistListFragment artistListFragment = new ArtistListFragment(); 
      Bundle artistData = new Bundle(); 
      artistData.putInt("current_page", i + 1); 
      artistListFragment.setArguments(artistData); 
      return artistListFragment; 

     case 1: 
      AlbumListFragment albumListFragment = new AlbumListFragment(); 
      Bundle albumData = new Bundle(); 
      albumData.putInt("current_page", i + 1); 
      albumData.putBoolean("showHeader", false); 
      albumListFragment.setArguments(albumData); 
      return albumListFragment; 

     default: 

      SongListFragment songListFragment = new SongListFragment(); 
      Bundle songData = new Bundle(); 
      songData.putInt("current_page", i + 1); 
      songListFragment.setArguments(songData); 
      return songListFragment; 
     } 
    } 

    /** Returns the number of pages */ 
    @Override 
    public int getCount() { 
     return PAGE_COUNT; 
    } 

    @Override 
    public CharSequence getPageTitle(int position) { 
     switch (position) { 
     case 0: 
      return "Artists"; 

     case 1: 
      return "Albums"; 

     default: 
      return "Songs"; 
     } 
    } 
} 

मुख्य एक्सएमएल (युक्त fragmentContainer & ViewPager):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/main_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/app_background_ics" > 

    <RelativeLayout 
     android:id="@+id/headingLayout" 
     android:layout_width="match_parent" 
     android:layout_height="56dp" > 
    </RelativeLayout> 

    <FrameLayout 
     android:id="@+id/fragmentContainer" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_below="@+id/headingLayout" /> 

    <android.support.v4.view.ViewPager 
     android:id="@+id/pager" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 

     <android.support.v4.view.PagerTabStrip 
      android:id="@+id/pager_title_strip" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="#33b5e5" 
      android:paddingBottom="4dp" 
      android:paddingTop="4dp" 
      android:textColor="#fff" /> 
    </android.support.v4.view.ViewPager> 

</RelativeLayout> 

उत्तर

3

इसे प्राप्त करने के लिए मुझे मिला एकमात्र तरीका निम्न है:

दृश्य पेज से दूर नेविगेट करते समय, Visiblity.GONE का उपयोग करके ViewPager को देखने के बाहर भेजें। बैकस्टैक में कोई भी खंड लेनदेन जोड़ें।

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

खंड Manager.getBackStackEntryCount() == 0, बैकस्टैक में कोई टुकड़े नहीं हैं।

यदि यह कथन सत्य है, तो बस दृश्यता का उपयोग करके ViewPager को वापस देखने के लिए लाएं। VISIBLE।

+1

हाँ! धन्यवाद। –

33

मुझे भी लंबे समय तक यह वही समस्या थी। समाधान बहुत आसान साबित हुआ है, और आपको ViewPager दृश्यता के साथ किसी भी हैक्स की आवश्यकता नहीं है। मैं इस दूसरे अतः संबंधित सवाल में वर्णित है: Fragment in ViewPager not restored after popBackStack

हालांकि, यह आसान बनाने के लिए, आप सभी की जरूरत अपने ViewPager अनुकूलक में getChildFragmentManager उपयोग करने के लिए(), बजाय getSupportFragmentManager की() है। तो, बजाय इस की:

/** Getting fragment manager */ 
    FragmentManager fm = getSupportFragmentManager(); 

    /** Instantiating FragmentPagerAdapter */ 
    MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm); 

    /** Setting the pagerAdapter to the pager object */ 
    mViewPager.setAdapter(pagerAdapter); 

आप ऐसा करते हैं:

/** Getting fragment manager */ 
    FragmentManager fm = getChildFragmentManager(); 

    /** Instantiating FragmentPagerAdapter */ 
    MyFragmentPagerAdapter pagerAdapter = new MyFragmentPagerAdapter(fm); 

    /** Setting the pagerAdapter to the pager object */ 
    mViewPager.setAdapter(pagerAdapter); 
+9

getChildFragmentManager() ठीक है अगर आपका व्यूपेजर फ्रैगमेंट के अंदर होस्ट किया गया है, लेकिन यदि ViewPager को FragmentActivity के अंदर होस्ट नहीं किया गया है। –

+0

आपका स्वागत है :) –

9

अद्यतन:
"एंड्रॉयड रास्ता" नहीं है यही कारण है कि और यह सूचीदृश्य के मामले के लिए बुरा उपयोगकर्ता अनुभव । इसके बजाय, एक नई गतिविधि बनाएं।

इस समस्या के लिए एक आसान समाधान खोजने वाले लोगों के लिए, मैं बस जो कुछ किया उसके बारे में बताऊंगा।

मेरे वास्तुकला:

  • ViewPager FragmentActivity में (ActionBarActivity वास्तव में, ActionBar समर्थन के लिए लेकिन ActionBarActivity लागू करता FragmentActivity।)।

  • 2 टैब:

    • FragmentContainer1 कि टुकड़ा फैली हुई है।
    • FragmentContainer2 जो टुकड़े को बढ़ाता है।

प्रत्येक FragmentContainer के लिए, हम उदाहरण के लिए onCreate विधि में getChildFragmentManager फोन, और टुकड़ा हम इस कंटेनर में दिखाना चाहते हैं जोड़ें:

FragmentToShow fragment = new FragmentToShow(); 

getChildFragmentManager() 
     .beginTransaction() 
     .add(R.id.container, fragment) 
     .commit(); 

हमने अपने पहले नहीं करना चाहते खंड को कंटेनर कंटेनर के बैकस्टैक में जोड़ा जाना चाहिए क्योंकि अगर हम बैक बटन दबाते हैं तो हम टुकड़े के कंटेनर को नहीं दिखाना चाहते हैं।

तो फिर, अगर हम (एक ListView साथ की तरह) हमारे FragmentToShow कक्षा में एक और टुकड़ा द्वारा FragmentToShow बदलना चाहते हैं:

Fragment itemFragment = new ItemFragment(); 

getFragmentManager() 
     .beginTransaction() 
     .replace(R.id.container, itemFragment) 
     .addToBackStack(null) 
     .commit(); 

यहाँ हम बच्चे टुकड़ा प्रबंधक को पुनः प्राप्त है, और हम वापस ढेर करने के लिए itemFragment जोड़ने ।

तो अब हम सूची दृश्य पर वापस जाने के लिए, बैक बटन दबाकर, देखना चाहते हैं (FragmentToShow इंस्टेंस)। हमारे गतिविधि (FragmentActivity) केवल एक वापस बटन के बारे में पता है, इसलिए हम इस गतिविधि में विधि onBackPressed() ओवरराइड करने के लिए है:

@Override 
public void onBackPressed() { 

    // We retrieve the fragment manager of the activity 
    FragmentManager frgmtManager = getSupportFragmentManager(); 

    // We retrieve the fragment container showed right now 
    // The viewpager assigns tags to fragment automatically like this 
    // mPager is our ViewPager instance 
    Fragment fragment = frgmtManager.findFragmentByTag("android:switcher:" + mPager.getId() + ":" + mPager.getCurrentItem()); 

    // And thanks to the fragment container, we retrieve its child fragment manager 
    // holding our fragment in the back stack 
    FragmentManager childFragmentManager = fragment.getChildFragmentManager(); 

    // And here we go, if the back stack is empty, we let the back button doing its job 
    // Otherwise, we show the last entry in the back stack (our FragmentToShow) 
    if(childFragmentManager.getBackStackEntryCount() == 0){ 
     super.onBackPressed(); 
    } else { 
     childFragmentManager.popBackStack(); 
    } 
} 

के बाद से हम अपने गतिविधि में getSupportFragmentManager कहते हैं, हम सिर्फ getFragmentManager में कॉल कर सकते हैं हमारे बच्चे के टुकड़े यह एक समर्थन FragmentManager उदाहरण वापस करेगा।

और यही वह है! मैं एक विशेषज्ञ नहीं हूं, इसलिए यदि आपके पास सुझाव या टिप्पणियां हैं, तो नि: शुल्क महसूस करें।

+0

धन्यवाद बहुत अच्छा है बैकप्रेस() ठीक काम करता है। – Androidbirt

+0

यह वास्तुकला मेरे लिए काम कर रही है। धन्यवाद :) – Dory

0

आप उपयोग कर रहे हैं ViewPager युक्त Fragments एक कि Activities शुरू कर सकते हैं, आपके द्वारा ठीक से वापस स्थिति के लिए ViewPager में कहा Activity (मानता है कि आपके ऊपर की ओर नेविगेशन के लिए घोषित राशि से नेविगेट होगा वापस मार या से नेविगेट करने पर है आपके Activities)।

पहले Activity को शुरू करने के लिए आपको में अतिरिक्त के रूप में ViewPager की वर्तमान स्थिति को पार करने की आवश्यकता है।

तो फिर तुम माता पिता Activity को उस स्थिति वापस पारित यह कर देगा:

Intent upIntent = NavUtils.getParentActivityIntent(this); 
upIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
upIntent.putExtra(FeedPagerActivity.EXTRA_POSITION, position); 
NavUtils.navigateUpTo(this, upIntent); 

भीतर है कि कोड रखो

onOptionsItemSelected (MenuItem आइटम)

+0

आप उत्तर स्पष्ट नहीं थे, क्या आप कुछ विचार या संबंधित लिंक दे सकते हैं, योगदान के लिए धन्यवाद। –

0

मुझे लगता है कि मैं ' एक बहुत ही समान समस्या थी।

ऐसा लगता है कि FragmentManager कुछ हद तक पदानुक्रमित तरीके से व्यवहार करता है। जिस तरह से मैंने इस समस्या को हल किया है, गतिविधि से "मुख्य" FragmentManager का उपयोग करना था, जो कंटेनर और व्यूपेजर होस्ट करता है, न कि एक, जिसे ViewPager के अंदर टुकड़ों से पुनर्प्राप्त किया जा सकता है।

ऐसा करने के लिए, मैं का उपयोग किया है:

this.getActivity().getSupportFragmentManager() 

जहां this टुकड़ा का एक उदाहरण है।

अब अगर मैं व्यूपार्जर में किसी आइटम से "प्रतिस्थापन" लेनदेन के साथ किसी अन्य खंड में नेविगेट करता हूं, तो लौटने पर मैं उस स्थिति में ViewPager देख सकता हूं जिसे मैंने छोड़ा है।

अधिक पूरा कोड नमूना इस तरह दिखता है:

FragmentManager fragmentManager = MyCurrentFragment.this.getActivity().getSupportFragmentManager(); 
FragmentTransaction transaction = fragmentManager.beginTransaction(); 

transaction.replace(R.id.container, newFragment); 
transaction.addToBackStack(null); 

transaction.commit(); 

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^