当前位置: 首页 > 知识库问答 >
问题:

Google Map ViewPager2滑动冲突

常乐
2023-03-14

有人在处理ViewPager2片段GoogleMap吗?

我遇到了一个非常有趣的问题,在我的viewpager中有两个选项卡,每个选项卡都呈现片段。

其中一个片段产生了谷歌地图。

当我尝试在地图上移动时,我得到了viewpager2尝试左右滑动的效果,这真的很烦人,所以我所做的解决方法并不太好。

我通过构造函数将视图寻呼机暴露给其中一个片段,并向顶部视图寻呼机活动发出回调。

在那里,我用逻辑执行了一个简单的isuserinputened,而map是active-disable-swipe。

一旦片段附加了这个回调,就会注册并调用逻辑。

片段分离后,此回调调用逻辑以重新启用。

这是一个解决方案,但在我看来并不好。还有更好的主意吗?

滑动与视图重叠对我来说似乎是一个错误。

/* top activity that hosts viewpager2 and it's tabs(fragments) */
class ViewTap extends AppCompatActivity
all the good stuff about viewpager2: ViewPager2
fun registerUi(){
...TapPagerAdapter(...this)
}
override fun fireSensitivityResolver(fragment: Fragment, flag: Boolean){
 if(fragment is ViewMapLoader){
  this.mViewPager2.isUserInputEnabled = !flag
 }
}

/* callback defintion fo handling events about Tab Capale thingies */
interface TabCapableIf {
 fun fireSensitivityResolver(fragment: Fragment, flag: Boolean)
}

/* the adapter for viewpager2 */
class TapPagerAdapter(...private val vt: ViewTap) : FragmentStateAdapter(fm,lc){
override fun createFragment(position: Int): Fragment {
return when(position) {
 ....
  CROWD_FRAGMENT -> { ViewCrowd(vmf, vt) }
 }
}

/* the fragment where the recycler view shows */
class ViewCrowd(...,val vt: ViewTap) : Fragment(){
 fun subscribeUi(){
   some recycler adapter = ItemViewCrowdsAdapter(...,this)
 }
}

/* the card adapter for the recycler view , when a card is clicked transition to map view */
class ItemViewCrowdsAdapter(...,private val vc: ViewCrowd) : AdapterFragmentRecyclerView(vm) {
 override fun onBindViewHolder(holder: ItemHolder, position: Int){
  ...holder.itemView.setOnClickListener{
   ...                    fragmentTransaction.replace(R.id.layout_view_crowd_root, ViewMapLoader(...,vc.vt))
  }
 }
}

/* the map loader context that shows the map and handles adjusting the sensitivity so that viewpager2 swipe doesn't overlap with map swipe functionality. otherwise as i try swiping on the map the viewpager2 also swipes. */
class class ViewMapLoader(...,private val vt: ViewTap) : Fragment() {
 private lateinit var mTabCapableIf: TabCapableIf
 override fun onAttach(...){
  this.mTabCapableIf = this.vt
  mTabCapableIf.fireSensitivityResolver(this,true)
 }

 override fun onDetach(){
  mTabCapableIf.fireSensitivityResolver(this,false)
 }
}

共有3个答案

丁子石
2023-03-14

我通过在地图上方添加一个愚蠢的视图解决了这个问题,如下所示:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <FrameLayout
        android:id="@+id/mapContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/mapShim"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

然后我简单地监听垫片上的触摸事件,将它们转发到映射容器,并防止父级收到使用Request estDislowInterceptTouchEvent(true)的通知:

mapShim.setOnTouchListener { _, event ->
    mapContainer.dispatchTouchEvent(event)
    mapContainer.parent.requestDisallowInterceptTouchEvent(true)
    true
}
张姚石
2023-03-14

如果要检测到用户在屏幕左边框或右边框附近启动滚动以滑动viewpager,则可以将dispatchTouchEvent()修改为(Kotlin):

private var intercept = false
private val slideBorder = 0.1 // width of the slide-border in percent of the screen width

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    when (ev.action) {
        MotionEvent.ACTION_DOWN -> {
           intercept = ev.x > width * slideBorder && ev.x < width * (1 - slideBorder)
        }
        MotionEvent.ACTION_MOVE -> {
            parent.requestDisallowInterceptTouchEvent(intercept)                                
        }                                                                                       
    }
    return super.dispatchTouchEvent(ev)
}
浦泳
2023-03-14

尝试覆盖MapView以抑制触摸事件

public class MapViewInScroll extends MapView {
public MapViewInScroll(Context context) {
    super(context);
}

public MapViewInScroll(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
}

public MapViewInScroll(Context context, AttributeSet attributeSet, int i) {
    super(context, attributeSet, i);
}

public MapViewInScroll(Context context, GoogleMapOptions googleMapOptions) {
    super(context, googleMapOptions);
}

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    getParent().requestDisallowInterceptTouchEvent(true);
    return super.dispatchTouchEvent(ev);
}

}

并在xml布局中使用它,而不是在原始MapView中使用它

                    <YOUR_PACKAGE.SOME_PATH_TO_VIEW.MapViewInScroll
                    android:id="@+id/map"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" />
 类似资料:
  • 我在寻呼机上有三个片段,三个片段都有回收视图。但在浏览回收站视图时,滚动条与之冲突。因此,只有在第三次或第四次轻扫之后,碎片才会被轻扫,或者有时我必须从屏幕开始到结束轻扫,然后碎片才会被重扫。我想要一个平滑的刷液。有人能帮我解决这个问题吗。谢谢

  • 本文向大家介绍Android listview的滑动冲突解决方法,包括了Android listview的滑动冲突解决方法的使用技巧和注意事项,需要的朋友参考一下 Android listview的滑动冲突解决方法 在Android开发的过程中,有时候会遇到子控件和父控件都要滑动的情况,尤其是当子控件为listview的时候。就比如在一个ScrollView里有一个listview,这种情况较常见

  • 本文向大家介绍Android侧滑菜单和轮播图之滑动冲突问题,包括了Android侧滑菜单和轮播图之滑动冲突问题的使用技巧和注意事项,需要的朋友参考一下 接手一个项目,有一个问题需要修改:轮播图不能手动滑动,手动滑动轮播图只会触发侧滑菜单。 猜测:viewpager控件(轮播图)的触摸事件被SlidingMenu控件(侧滑菜单,非第三方项目,乃是上个开发人员自定义的)拦截了。 基于这个猜测,我自定义

  • 本文向大家介绍Android滑动事件冲突的解决方法,包括了Android滑动事件冲突的解决方法的使用技巧和注意事项,需要的朋友参考一下 滑动是Android中不可缺少的一部分,多个滑动必然会产生冲突,比如我们最常见的是ScrollView中嵌套了ListView,一般做法是计算出ListView的总高度,这样就不用去滑动ListView了。又比如一个ViewPager嵌套Fragment,Frag

  • 本文向大家介绍浅谈Android View滑动冲突的解决方法,包括了浅谈Android View滑动冲突的解决方法的使用技巧和注意事项,需要的朋友参考一下 引言 这一篇文章我们就通过介绍滑动冲突的规则和一个实例来更加深入的学习View的事件分发机制。 1、外部滑动方向和内部滑动方向不一致 考虑这样一种场景,开发中我们经常使用ViewPager和Fragment配合使用所组成的页面滑动效果,很多主流

  • 本文向大家介绍Android解决viewpager嵌套滑动冲突并保留侧滑菜单功能,包括了Android解决viewpager嵌套滑动冲突并保留侧滑菜单功能的使用技巧和注意事项,需要的朋友参考一下 重写子pagerview的dispatchTouchEvent方法,在返回前添加一句getParent().requestDisallowInterceptTouchEvent(true)中断掉事件的传递