2013-08-26 73 views
6

我使用viewpager在片段之間滑動,並希望後退按鈕導航到先前查看的片段,而不是結束活動。對不起,如果這是this question的重複,但我沒有找到答案非常有幫助。顯然OnBackPressed需要被覆蓋,但我不知道如何獲取並顯示正確的片段。我假設我應該使用fragmentmanager的backstack,但getSupportFragmentManager().getBackStackEntryCount()總是返回0.我是否需要使用FragmentTransaction.addToBackStack()手動將碎片添加到backstack?如果是這樣,我會在我的適配器中添加它?在viewpager中使用backstack和後退按鈕

這裏是我的活動代碼,

public class PagerActivity extends FragmentActivity { 

ArrayList<Sale> sales; 
MyAdapter mAdapter; 
ViewPager mPager; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent it = getIntent(); 
    this.sales = (ArrayList<Sale>) it.getExtras().get("sales"); 
    int position = it.getExtras().getInt("position"); 

    ActionBar actionBar = getActionBar(); 
    actionBar.setDisplayHomeAsUpEnabled(true); 

    setContentView(R.layout.fragment_pager); 
    mAdapter = new MyAdapter(getSupportFragmentManager()); 
    mPager = (ViewPager) findViewById(R.id.pager); 
    mPager.setAdapter(mAdapter); 
    mPager.setCurrentItem(position); 

} 

public class MyAdapter extends FragmentPagerAdapter { 
    public MyAdapter(FragmentManager fragmentManager) { 
     super(fragmentManager); 
    } 

    @Override 
    public int getCount() { 
     return sales.size(); 
    } 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     super.destroyItem(container, position, object); 
    } 

    @Override 
    public Fragment getItem(int position) { 
     SalesThumbFragment frag = new SalesThumbFragment(); 
     return frag.newInstance(sales.get(position)); 
    } 
} 

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

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.sales_controller, menu); 
    return true; 
} 

@Override 
public void onBackPressed() { 
    if(getSupportFragmentManager().getBackStackEntryCount() != 0) { 
    getSupportFragmentManager().popBackStack(); 
    } else { 

    super.onBackPressed(); 
    } 
} 


} 

回答

0

如果你使用一個字段,以保持每個用戶導航到一個新的碎片時間後使用mPager.getCurrentItem()前一頁面的索引軌道,然後在onBackPressed()方法,你應該能夠調用mPager.setCurrentItem(previousPage)

或者,如果用戶只能在頁面順序,那麼你並不需要一個場可言的,你可以只是做mPager.setCurrentItem(mPager.getCurrentItem()-1)

+0

用戶可以在任何方向導航,所以第二個解決方案將無法工作。我剛剛試圖通過添加一個OnPageChangeListener實現第一個解決方案,並在那裏記錄索引,但行爲不一致。有時顯示的頁面不會改變,即使我可以從日誌中看到下一個片段正在被實例化。 – Igd

+0

另外,手動跟蹤索引感覺就像是一個漂亮的'un-android'解決方案,因爲後臺已經存在這個目的 – Igd

+2

嗯,我不知道爲什麼會有這種不一致,但重要的是要注意ViewPager實際上在任何時候都會在內存中實例化3個頁面:當前頁面,前一頁面和下一頁面。因此,如果您當前位於第2頁(第1,2和3頁當前正在實例化),然後轉到第3頁,則第4頁將被實例化並且第1頁將被刪除。 –

1

我有類似的問題,這是我解決它的方法。如果我明白你的問題所在,我認爲你可以將代碼適應你的問題。我有一個ViewPager 6片段,並希望跟蹤頁面歷史記錄,並能夠使用後退按鈕在歷史中向後導航。我創建一個java.util.Stack<Integer>對象,爲它添加片段編號(除了當您使用後退按鈕時,請參見下文),並覆蓋onBackPressed()以使其彈出最後查看的片段而不是使用後退堆棧,當我的歷史堆棧不爲空時。

當您按下後退按鈕時,您希望避免在堆棧上推送元素,否則如果繼續使用後退按鈕而不是最終退出,您將卡在兩個碎片之間。

我的代碼:

MyAdapter mAdapter; 
ViewPager mPager; 
Stack<Integer> pageHistory; 
int currentPage; 
boolean saveToHistory; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mAdapter = new MyAdapter(getSupportFragmentManager()); 
    mPager = (ViewPager)findViewById(R.id.container); 
    mPager.setAdapter(mAdapter); 
    mPager.setOffscreenPageLimit(5); 

    pageHistory = new Stack<Integer>(); 
    mPager.setOnPageChangeListener(new OnPageChangeListener() { 

     @Override 
     public void onPageSelected(int arg0) { 
      if(saveToHistory) 
       pageHistory.push(Integer.valueOf(currentPage)); 
     } 

     @Override 
     public void onPageScrolled(int arg0, float arg1, int arg2) { 
     } 

     @Override 
     public void onPageScrollStateChanged(int arg0) { 
     } 
    }); 
    saveToHistory = true; 
} 

@Override 
public void onBackPressed() { 
    if(pageHistory.empty()) 
     super.onBackPressed(); 
    else { 
     saveToHistory = false; 
     mPager.setCurrentItem(pageHistory.pop().intValue()); 
     saveToHistory = true; 
    } 
}; 
2

使用此代碼片段Activity類。不要忘記添加返回true;

public boolean onKeyDown(int keyCode, KeyEvent event) { 

    // TODO Auto-generated method stub 
    if ((keyCode == KeyEvent.KEYCODE_BACK)) { 

      mViewPager.setCurrentItem(viewPageSelected - 1); 
      return true; 
     } 

    return super.onKeyDown(keyCode, event); 

} 
8

在新的設計支持庫,我用這個
我有同樣的問題,我按照此步驟

在主要活動,其中有在viewpager我創建堆棧 加推3片段和流行數據。

//private Stack<Integer> stackkk; ==> As i get edit suggestion 
private Stack<Integer> stackkk = new Stack<>(); // Edited 
private ViewPager mPager; 
private int tabPosition = 0; 



    mTabLayout.setupWithViewPager(mPager); 
    mPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout)); 
    mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
     @Override 
     public void onTabSelected(TabLayout.Tab tab) { 
      tabPosition = tab.getPosition(); 
      mPager.setCurrentItem(tab.getPosition()); 

      if (stackkk.empty()) 
       stackkk.push(0); 

      if (stackkk.contains(tabPosition)) { 
       stackkk.remove(stackkk.indexOf(tabPosition)); 
       stackkk.push(tabPosition); 
      } else { 
       stackkk.push(tabPosition); 
      } 
     } 

     @Override 
     public void onTabUnselected(TabLayout.Tab tab) { 
      tabPositionUnselected = tab.getPosition(); 
     } 

     @Override 
     public void onTabReselected(TabLayout.Tab tab) { 
     } 
    }); 
} 

,並在onBackPressed的活動,

@Override 
public void onBackPressed() { 
    if (stackkk.size() > 1) { 
     stackkk.pop(); 
     mPager.setCurrentItem(stackkk.lastElement()); 
    } else { 
    } 
} 
+0

感謝您的編輯建議,因爲我已更改我的代碼 表格 私人堆棧 stackkk; 至 private Stack stackkk = new Stack <>(); 每次創建一個新對象。 –

0

我做了定製ViewPager,並在其中實現堆疊功能。

public class CustomViewPager extends ViewPager { 

private Stack<Integer> stack = new Stack<>(); 

@Override 
public void setCurrentItem(int item, boolean smoothScroll) { 
    stack.push(getCurrentItem()); 
    super.setCurrentItem(item, smoothScroll); 
} 

public int popFromBackStack(boolean smoothScroll) { 
    if (stack.size()>0) { 
     super.setCurrentItem(stack.pop(), smoothScroll); 
     return getCurrentItem(); 
    } else return -1; 
}