You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ViewPager2拍照/授权返回后自动跳页问题求助

问题描述

我正在开发一个基于ViewPager2的项目,其中一个TakePictureFragment需要申请相机权限并拍摄照片,拍摄完成后本应在该Fragment中显示照片,但返回该Fragment时会自动跳转到下一页且无任何报错,请问如何实现仅在用户点击按钮时才执行页面跳转?


ViewActivity 代码

class ViewActivity : BaseActivity() {

   private lateinit var binding: ActivityView
   private lateinit var adapter: PagerAdapter

   override fun onCreate(savedInstanceState: Bundle?){ 
      super.onCreate(savedInstanceState)

      adapterViewPager()
      goToNextPage()
      goToBackPage()
   }

   private fun adapterViewPager(){
      adapter = ViewAdapter(supportFragmentManager, lifecycle)

      adapter.addFragment(HelloWordFragment())
      adapter.addFragment(TakePictureFragment())
      adapter.addFragment(LoginFragment())
      adapter.addFragment(ConfirmEmailFragment())

      binding.viewPager.adapter = adapter
   }

   private fun goToNextPage(){
      binding.viewPager.setCurrentItem(binding.viewPager.currentItem + 1)
   }
 
   private fun goToBackPage(){
      binding.viewPager.setCurrentItem(binding.viewPager.currentItem - 1)
   }
}

PagerAdapter(Java)代码

public final class PagerAdapter extends FragmentStateAdapter {

   private final List<Fragment> fragList = new ArrayList<>() 

   ViewAdapter(FragmentManager fm, Lifecycle lf){
      super(fm, lf)
   }

   public Fragment createViewPager(int position){
      return fragList.get(position)
   }

   public void addFragment(Fragment fragment){
      fragList.add(fragment)
   }
}

TakePictureFragment 代码

class TakePictureFragment : Fragment() {
   
   private lateinit var binding : FragmentTakePicture

   override fun onCreateView(
      inflater: LayoutInflater, container: ViewGroup?,
      savedInstanceState: Bundle?
   ): View {
      binding = FragmentTakePicture.inflate(layoutInflater, container, false)
      return binding.root
   }

   override fun onViewCreated(view: View, savedInstanceState: Bundle?){ 
      super.onViewCreated(view, savedInstanceState)

      next()
   }

   override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
      super.onActivityResult(requestCode, resultCode, data)
      if (resultCode == RESULT_OK) {
            when (requestCode) {
                REQUEST_IMAGE_CAPTURE -> {...}
                REQUEST_GALLERY_IMAGE -> {...}
            }
      }
   }

   private fun next(){
      binding.buttonNext.setOnClickListener {
         parent.goToNextPage()
      }
   }
}

解决方案

问题根源

  1. ViewActivity的onCreate方法中直接调用了goToNextPage()和goToBackPage(),这会导致Activity启动时自动执行页面跳转;当从相机返回时,若Activity发生重建,onCreate会再次执行,触发自动跳页。
  2. Java版PagerAdapter未正确重写FragmentStateAdapter的必要方法,自定义的createViewPager无法被ViewPager2识别,可能引发Fragment生命周期异常,间接导致页面跳转问题。

修复步骤

  1. 移除自动跳转的初始化代码
    在ViewActivity的onCreate中删除直接调用goToNextPage()和goToBackPage()的语句,仅保留ViewPager初始化逻辑:

    override fun onCreate(savedInstanceState: Bundle?){ 
       super.onCreate(savedInstanceState)
    
       adapterViewPager()
       // 移除 goToNextPage() 和 goToBackPage() 调用
    }
    
  2. 修正PagerAdapter的核心方法
    重写FragmentStateAdapter要求的createFragment和getItemCount方法,并添加数据更新通知:

    public final class PagerAdapter extends FragmentStateAdapter {
    
       private final List<Fragment> fragList = new ArrayList<>();
    
       public PagerAdapter(FragmentManager fm, Lifecycle lf){
          super(fm, lf);
       }
    
       @NonNull
       @Override
       public Fragment createFragment(int position){
          return fragList.get(position);
       }
    
       @Override
       public int getItemCount() {
          return fragList.size();
       }
    
       public void addFragment(Fragment fragment){
          fragList.add(fragment);
          notifyDataSetChanged(); // 通知适配器更新数据
       }
    }
    
  3. 确保跳转逻辑仅绑定按钮点击
    优化TakePictureFragment中获取Activity的方式,避免空指针,确保只有点击按钮时才触发跳转:

    private fun next(){
       binding.buttonNext.setOnClickListener {
          (activity as? ViewActivity)?.goToNextPage()
       }
    }
    
  4. 保存并恢复ViewPager页面状态
    在ViewActivity中保存当前页面位置,避免Activity重建后页面重置:

    override fun onSaveInstanceState(outState: Bundle) {
       super.onSaveInstanceState(outState)
       outState.putInt("current_page", binding.viewPager.currentItem)
    }
    
    override fun onCreate(savedInstanceState: Bundle?){ 
       super.onCreate(savedInstanceState)
    
       adapterViewPager()
       // 恢复之前的页面位置
       savedInstanceState?.let {
          binding.viewPager.setCurrentItem(it.getInt("current_page"), false)
       }
    }
    

内容的提问来源于stack exchange,提问作者ShawDD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:45:45