【问题标题】:Navigation Error: action/destination cannot be found from the current destination导航错误:无法从当前目的地找到操作/目的地
【发布时间】:2021-06-14 08:38:06
【问题描述】:

我正在使用导航组件在两个片段之间导航。登陆片段有一个回收器视图,而细节片段有一个视图分页器。我正在使用回调侦听器从回收器视图适配器触发导航操作。

要触发的动作是缩放事件,库ZoomHelper ZoomHelper

当事件发生时,应用程序崩溃并出现上述错误。

不过它与 onclick 事件监听器配合得很好。

查看支架

class CampaignListViewHolder<T : ViewBinding>(private val binding: T) : RecyclerView.ViewHolder(binding.root) {

    var campaignDetails: CampaignDetails? = null

    @SuppressLint("ClickableViewAccessibility")
    fun bindTo(campaignDetails: CampaignDetails?, position: Int, listener: ItemZoomListener) {
        this.campaignDetails = campaignDetails

        binding as CampaignItemLayoutBinding
        binding.campaignNameTv.text = campaignDetails?.name
        binding.campaignImageIv.load(campaignDetails?.image?.url) {
            crossfade(true)
            placeholder(R.drawable.westwing_placeholder)
        }
        ViewCompat.setTransitionName(binding.campaignImageIv, campaignDetails?.name)
        binding.root.setOnClickListener {
            if (campaignDetails != null) {
                listener.navigate(position)
            }
        }

        ZoomHelper.addZoomableView(binding.campaignImageIv)
        
        ZoomHelper.getInstance().addOnZoomScaleChangedListener(object :
                ZoomHelper.OnZoomScaleChangedListener {
                override fun onZoomScaleChanged(
                    zoomHelper: ZoomHelper,
                    zoomableView: View,
                    scale: Float,
                    event: MotionEvent?
                ) {
                    // called when zoom scale changed
                  
                    if (campaignDetails != null && scale > 1.4) {
                        listener.navigate(position)
                    }
                }
            })
    }
}

着陆片段

class LandingFragment : Fragment(R.layout.fragment_landing), ItemZoomListener, FragmentUiStateListener {
    private val TAG by lazy { getName() }
    private val binding by viewBinding(FragmentLandingBinding::bind)
    private val campaignListViewModel: CampaignListViewModel by activityViewModels()
    lateinit var campaignViewAdapter: CampaignListViewAdapter
    lateinit var activityUiState: ActivityUiStateListener
    lateinit var fragmentUiUpdate: FragmentUiStateListener

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        campaignViewAdapter = CampaignListViewAdapter(this)
        fragmentUiUpdate = this
    }

    override fun onResume() {
        super.onResume()
        setupView()
        setUpData()
    }

    private fun setUpData() {
        setUpUiState(campaignListViewModel.campaignUiState, fragmentUiUpdate)
    }

    private fun setupView() {
        val orientation = checkOrientation()
        if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            binding.campaignLandscapeRcv?.apply {
                layoutManager = GridLayoutManager(requireContext(), 2)
                adapter = campaignViewAdapter
                addItemDecoration(ItemSpaceDecoration(8, 2))
            }
        } else {
            binding.campaignListRcv?.apply {
                layoutManager = LinearLayoutManager(requireContext())
                adapter = campaignViewAdapter
                addItemDecoration(ItemSpaceDecoration(8, 1))
            }
        }
    }

    override fun navigate(position: Int) {
        val direction = LandingFragmentDirections.actionLandingFragmentToCampaignDetailsFragment(position)
        goto(direction)
    }



我了解错误的原因之一可能是缩放事件多次调用导航控制器,但我不知道如何调试以及解决此问题的方法。

【问题讨论】:

    标签: android kotlin android-fragments


    【解决方案1】:

    正如您所猜测的,该问题很可能是由多次触发 navController 引起的。您可以通过“安全导航”来处理此问题。下面是一个示例实现:

    fun NavController.safelyNavigate(@IdRes resId: Int, args: Bundle? = null) = 
        try { navigate(resId, args) }
        catch (e: Exception) { Timber.e(e) }
    }
    

    然后您可以像这样进行导航调用:

    findNavController().safelyNavigate(your_id)
    

    这样,对 NavController.navigate() 的任何额外调用都会被try and catch 所吸引。

    防止崩溃:D

    【讨论】:

      【解决方案2】:

      如果有人由于多次点击屏幕而遇到同样的问题。可以通过在导航前先检查当前目的地来解决

      例如

      片段 A、B 和 C

      在单击片段 A 中导航到 C 的按钮时从 A 导航到 B 在某些情况下可能会导致崩溃

      为此,您应该首先检查当前目的地,如下所示:

      if(findNavController().currentDestination?.id==R.id.AFragment)
         findNavController().navigate(
         AFragmentDirections.actionAFragmentToCFragment()
       )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-19
        • 2021-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 2021-10-15
        相关资源
        最近更新 更多