我正在使用viewpager在片段之间滑动,并希望后退按钮导航到先前查看的片段而不是结束活动。很抱歉,如果这是this question的副本,但我没有找到答案非常有帮助。显然onBackPressed需要被覆盖,但我不知道如何获取并显示正确的片段。我假设我应该使用fragmentmanager的backstack,但是getSupportFragmentManager().getBackStackEntryCount()
总是返回0.我是否需要使用FragmentTransaction.addToBackStack()
手动将片段添加到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 :(得分: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 in activity中,
@Override
public void onBackPressed() {
if (stackkk.size() > 1) {
stackkk.pop();
mPager.setCurrentItem(stackkk.lastElement());
} else {
}
}
答案 1 :(得分:2)
在Fragment Activity类中使用此代码。不要忘记添加return 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);
}
答案 2 :(得分:1)
我有类似的问题,这就是我解决它的方法。如果我明白你的问题,我认为你可以根据你的问题调整代码。我有一个包含6个片段的ViewPager,想要跟踪页面历史记录,并能够使用后退按钮在历史记录中向后导航。我创建一个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;
}
};
答案 3 :(得分:0)
如果您在每次用户导航到新片段后使用字段跟踪上一页的索引,则使用mPager.getCurrentItem()
,然后在onBackPressed()
方法中,您应该能够致电mPager.setCurrentItem(previousPage)
或者,如果用户只能按顺序分页,那么根本不需要字段,您可以mPager.setCurrentItem(mPager.getCurrentItem()-1)
答案 4 :(得分: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;
}