2014-02-26 51 views
0

我一直在這個問題上停留了幾天,這讓我發瘋。這似乎是我想要做的將是一個很常見的用例,但我不能爲我的生活弄清楚。如何更換ViewPager中的片段

所以,問題:我想更換ViewPager中的片段並保持backstack的正常運行。

我的ViewPager包含兩個顯示ListView的片段。當ViewPager的第一位置,我希望能夠深入到ListView和能夠與後退按鈕退了出去,像這樣:

藝術家 - >專輯 - >歌曲

藝術家< - 專輯< - 歌曲

這些元素中的每一個都是作爲包含它自己的ListView的獨立片段實現的。

當用戶向右滑動時,我想使用ViewPager將當前播放列表顯示在單獨的片段中。

因此,一個典型的流程可能是:

藝術家 - >專輯 - >Swipe Right to Playlist fragment - >播放列表 - >Swipe Left to return - >相冊

多次試驗後我設法想出這個解決方案,它確實取代了的藝術家/唱片集的片段,但是它不可能使用後退按鈕回退片段:

public interface ItemSelectedListener { 
    void onItemSelected(Item item); 
} 

public class ListPagerAdapter extends FragmentPagerAdapter { 
    private static final String TAG = RMPDApplication.APP_PREFIX + "ListPagerAdapter"; 
    SearchView searchView; 
    FragmentManager fragmentManager; 
    AbstractListFragment firstFragment; 
    PlaylistFragment playlistFragment; 


    public ListPagerAdapter(SearchView searchView, FragmentManager fm) { 
     super(fm); 
     this.searchView = searchView; 
     fragmentManager = fm; 
    } 

    class FragmentChanger implements ItemSelectedListener { 
     @Override 
     public void onItemSelected(Item item) { 
      AbstractListFragment newFragment; 
      if (item instanceof Artist) { 
       newFragment = new ArtistAlbumsListFragment(searchView, (Artist) item, new FragmentChanger()); 
      } else { 
       newFragment = new SongListFragment(searchView, (Album) item); 
      } 

      FragmentTransaction ft = fragmentManager.beginTransaction(); 
      ft.remove(firstFragment); 
      ft.commit(); 
      firstFragment = newFragment; 
      notifyDataSetChanged(); 
     } 
    } 


    @Override 
    public Fragment getItem(int position) { 
     if (position == 1) { 
      Log.i(TAG, "Returning playlistFragment"); 
      if (playlistFragment == null) { 
       playlistFragment = new PlaylistFragment(searchView); 
      } 
      return playlistFragment; 

     } else { 
      Log.i(TAG, "Returning firstFragment"); 
      if(firstFragment == null) { 
       firstFragment = new ArtistListFragment(new FragmentChanger(), searchView); 
      } 
      return firstFragment; 
     } 
    } 

    @Override 
    public int getCount() { 
     return 2; 
    } 

    @Override 
    public int getItemPosition(Object object) { 
     Log.i(TAG, "getItemPosition: " + object.getClass().getSimpleName()); 
     if(object instanceof PlaylistFragment) { 
      return POSITION_UNCHANGED; 
     } 
     return POSITION_NONE; 
    } 
} 

我通過FragmentChanger到每個片段,然後在onItemClick()我調用它的唯一方法:

@Override 
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
    final Artist artist = (Artist) adapter.getItem(position); 
    itemSelectedListener.onItemSelected(artist); 
} 

這幾乎工程,單擊某個項目替換所期望的一個片段,但我沒有辦法恢復到以前的片段。如果有人能幫我弄清楚這一點,我會非常感激。

編輯:

好,我得到了它與J.Romero的建議工作。最後,我在單個BrowserFragment中實現了所有前進/後退功能,並且取消onBackPressed()來處理後退按鈕。我會添加相關代碼以防別人幫助。

這裏是我的ViewPager:

public class ListPagerAdapter extends FragmentPagerAdapter { 
    SearchView searchView; 
    BrowserFragment browserFragment; 
    PlaylistFragment playlistFragment; 

    public ListPagerAdapter(SearchView searchView, FragmentManager fm) { 
     super(fm); 
     this.searchView = searchView; 
    } 

    public boolean browserFragmentCanGoBack() { 
     return browserFragment.canGoBack(); 
    } 

    public void browserFragmentBack() { 
     browserFragment.goBack(); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     if (position == 1) { 
      if (playlistFragment == null) { 
       playlistFragment = new PlaylistFragment(searchView); 
      } 
      return playlistFragment; 

     } else { 
      if (browserFragment == null) { 
       browserFragment = new BrowserFragment(searchView); 
      } 
      return browserFragment; 
     } 
    } 

    @Override 
    public int getCount() { 
     return 2; 
    } 
} 

然後在舉辦活動我重寫onBackPressed()這樣的:

@Override 
public void onBackPressed() { 
    if (viewPager.getCurrentItem() == 0) { 
     if (pagerAdapter.browserFragmentCanGoBack()) { 
      pagerAdapter.browserFragmentBack(); 
     } else { 
      super.onBackPressed(); 
     } 
    } else { 
     viewPager.setCurrentItem(viewPager.getCurrentItem() - 1); 
    } 
} 

和它的作品!

回答

2

您可以通過在活動中重寫onBackPressed方法來管理「backstack」,並跟蹤用戶當前處於哪個級別,並顯示或返回以及適當的活動。

@Override 
public void onBackPressed(){ 
    if (mLevel > 1) { 
     // in your case probably change the adapter item for the page 
     mViewPagerAdapter.notifyDataSetChanged() 
    } 
    ... 
} 
+0

多數民衆贊成在一個好主意,我會給它之前,並報告回來。 – facetoe