我一直在這個問題上停留了幾天,這讓我發瘋。這似乎是我想要做的將是一個很常見的用例,但我不能爲我的生活弄清楚。如何更換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);
}
}
和它的作品!
多數民衆贊成在一個好主意,我會給它之前,並報告回來。 – facetoe