我正在使用导航组件在两个片段之间导航。着陆片段具有回收程序视图,详细信息片段具有视图页。我正在使用回调侦听器从回收程序视图适配器触发导航操作。
要触发的动作是缩放事件,其库为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)
}
我知道错误的原因之一可能是缩放事件多次调用导航控制器,但我不知道如何调试,以及什么可以是一种方法来解决这个问题。
3条答案
按热度按时间soat7uwm1#
正如你所猜测的,这个问题很可能是由navController被多次触发引起的。你可以通过“安全导航”来处理这个问题。下面是一个示例实现:
然后,您可以按如下方式进行导航调用:
这样,对 NavController.navigate() 的任何额外调用都会被try和catch吸收。
防止崩溃:D
fwzugrvs2#
如果有人由于多次点击屏幕而遇到同样的问题。可以通过在导航前先检查当前目的地来解决
例如
片段A、B和C
在某些情况下,当单击片段A中导航到C的按钮时,从A导航到B可能会导致崩溃
为此,您应该首先检查当前目标,如下所示:
jtoj6r0c3#
如果它被调用了两次,则可以在导航发生之前删除“ZoomHelper.OnZoomScaleChangedListener”。
我还没有测试下面的代码,但是你可以在这里探索这个库的代码https://github.com/Aghajari/ZoomHelper/blob/master/ZoomHelper/src/main/java/com/aghajari/zoomhelper/ZoomHelper.kt。你会发现一个名为'removeOnZoomScaleChangedListener'的方法,据我所知,它将删除一个类型为'ZoomHelper.OnZoomScaleChangedListener'的监听器。
前。