我正在使用ViewPager在我的Android应用中实现滑动。但是,我想在用户使用后退按钮而不是结束活动时显示前一个片段。有没有办法做到这一点? 谢谢 塞巴斯蒂安
答案 0 :(得分:5)
我有类似的问题,这就是我解决它的方法。我有一个包含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;
}
};
答案 1 :(得分:4)
覆盖Activity
的功能:
public class Activity extends Activity
{
@Override
public void onBackPressed()
{
// do stuff
myFragment.onBackPressed();
}
}
public class Fragment extends Fragment
{
public void onBackPressed()
{
// do stuff
}
}
答案 2 :(得分:1)
我有同样的问题,我按照这一步(编辑我的答案---当然为我工作,试一试)
在viewpager中有3个片段的主要活动中,我创建堆栈 和推送和弹出数据。
private Stack<Integer> stackkk;
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());
// here i have add the data into the stack in each tab click, as at first it will always be null so i add 0 position
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中,
//OnbackPress i have first taken out the last one as it already and
//selected by poping it out then only set to the pager.
@Override
public void onBackPressed() {
if (stackkk.size() > 1) {
stackkk.pop();
mPager.setCurrentItem(stackkk.lastElement());
} else {
}
}
希望这可以帮助或告诉我。
答案 3 :(得分:0)
在Fragment Activity中覆盖以下方法应该可以解决您的问题。
@Override
public void onBackPressed() {
if (mViewPager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mViewPager.setCurrentItem(mViewPager.getCurrentItem() - 1);
}
}
答案 4 :(得分:0)
如果您使用的是Jetpack Navigation组件,则您可能只有一个活动,并试图管理片段中的Backstack。 在这种情况下,OnBackPressedDispatcher会派上用场。
答案 5 :(得分:0)
参考@Piero Nicolli 代码和 kotlin
此 anwser 将与 Instagram 导航相同 一旦你访问了同一个标签,你就不会再次访问它
val pageHistory = Stack<Int>()
var saveToHistory = false
var viewPager: ViewPager? = null
在 Oncreate 或 OncreateView 中(如果您在 Fragment 中使用 viewPager)
viewPager?.adapter = viewPagerAdapter
pageHistory.push(0);
viewPager?.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(
position: Int,
positionOffset: Float,
positionOffsetPixels: Int,
) {
}
override fun onPageSelected(position: Int) {
if (saveToHistory) {
if (pageHistory.contains(position)) {
pageHistory.remove(position)
pageHistory.push(position);
} else {
pageHistory.push(position);
}
}
}
override fun onPageScrollStateChanged(state: Int) {
}
})
saveToHistory = true;
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
// Handle the back button event
Log.i(TAG, "pageHistory size ${pageHistory.size}")
if (pageHistory.size > 1) {
saveToHistory = false;
pageHistory.pop()
viewPager?.currentItem = pageHistory.peek()
saveToHistory = true;
} else {
Log.i(TAG, "pageHistory inside 0 size ${pageHistory.size}")
if(pageHistory.size ==1){
pageHistory.pop()
}
if (viewPager?.currentItem == 0){
requireActivity().finish()
}else{
viewPager?.currentItem = 0
}
}
}
当我使用 Fragment 时,后退按钮有回调 onBackPressedDispatcher。 如果您在 Activity 中使用 viewpager,则将代码从 onBackPressedDispatcher() 复制到 onBackPressed()