用于在 Scrollview 中移动 Google 地图的 Android SupportMapFragment

Posted

技术标签:

【中文标题】用于在 Scrollview 中移动 Google 地图的 Android SupportMapFragment【英文标题】:Android SupportMapFragment for moving Google Map within Scrollview 【发布时间】:2021-06-03 06:45:48 【问题描述】:

我想在垂直 ScrollView 中设置一个谷歌地图子片段。为了解决垂直平移不滚动的问题,我尝试使用这种方法Google Map Fragment scrolling inside NestedScrollView,但是在地图内部移动时滚动视图并没有停止。

这是我的 xml

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/scroll_view"
    android:layout_
    android:layout_
    android:layout_marginStart="16dp"
    android:layout_marginTop="10dp"
    android:layout_marginEnd="16dp"
    android:layout_marginBottom="10dp"
    android:fadeScrollbars="false"
    android:padding="0dp"
    tools:context=".fragments.add.AddFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_
        android:layout_
        android:padding="0dp">

        <TextView
            android:id="@+id/textView_text1"
            android:layout_
            android:layout_
            android:layout_marginTop="30dp"
            android:ems="10"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

<fragment
            android:id="@+id/map"
            android:name="com.example.myapp.fragments.add.MySupportMapFragment"
            android:layout_
            android:layout_
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:layout_marginEnd="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView_text1"
            app:mapType="normal" />

</androidx.constraintlayout.widget.ConstraintLayout>

</ScrollView>

MySupportMapFragment


import android.R
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import com.google.android.gms.maps.SupportMapFragment


class MySupportMapFragment : SupportMapFragment() 
    private var mListener: OnTouchListener? = null
    override fun onCreateView(
        inflater: LayoutInflater,
        parent: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        val layout: View? = super.onCreateView(inflater, parent, savedInstanceState)
        val frameLayout = TouchableWrapper(activity)
        frameLayout.setBackgroundColor(resources.getColor(R.color.transparent))
        (layout as ViewGroup?)!!.addView(
            frameLayout,
            ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT
            )
        )
        return layout
    

    fun setListener(listener: OnTouchListener?) 
        mListener = listener
    

    interface OnTouchListener 
        fun onTouch()
    

    inner class TouchableWrapper(context: Context?) : FrameLayout(context!!) 
        override fun dispatchTouchEvent(event: MotionEvent): Boolean 
            when (event.action) 
                MotionEvent.ACTION_DOWN -> mListener!!.onTouch()
                MotionEvent.ACTION_UP -> mListener!!.onTouch()
            
            return super.dispatchTouchEvent(event)
        
    

还有我的代码

class AddFragment : Fragment() 

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_add, container, false)

          val mapFragment = childFragmentManager.findFragmentById(R.id.map) as MySupportMapFragment

          mapFragment.getMapAsync(object:OnMapReadyCallback 
                override fun onMapReady(googleMap:GoogleMap) 
                    mMap = googleMap

                    with(googleMap) 
                        // We will provide our own zoom controls.
                        uiSettings.isZoomControlsEnabled = true
                        uiSettings.isMyLocationButtonEnabled = true
                        uiSettings.isScrollGesturesEnabled = true
                        this.mapType = GoogleMap.MAP_TYPE_HYBRID


                        moveCamera(CameraUpdateFactory.newLatLngZoom(StartPosition, 10f))
                    


                    mMap.setOnCameraIdleListener(object : GoogleMap.OnCameraIdleListener 
                        override fun onCameraIdle()  
                            mPositionLatitude = mMap.getCameraPosition().target.latitude
                            mPositionLongitude = mMap.getCameraPosition().target.longitude
                        
                    )


                    var mScrollView  = view.findViewById(R.id.scroll_view) as ScrollView
                   mapFragment.setListener(object :
                        MySupportMapFragment.OnTouchListener 
                        override fun onTouch() 
                            mScrollView.parent.requestDisallowInterceptTouchEvent(true)
                        
                    )


                
            )
 return view
    

    


【问题讨论】:

【参考方案1】:

在我的应用程序中遇到同样的问题,我使用自定义 Scrollview 拦截滚动视图触摸来解决此问题

自定义滚动视图:

public class CustomScrollView extends ScrollView 

public CustomScrollView(Context context) 
    super(context);


public CustomScrollView(Context context, AttributeSet attrs) 
    super(context, attrs);


public CustomScrollView(Context context, AttributeSet attrs, int defStyle) 
    super(context, attrs, defStyle);


@Override
public boolean onInterceptTouchEvent(MotionEvent ev) 
    final int action = ev.getAction();
    switch (action) 
        case MotionEvent.ACTION_DOWN:
            //Log.i("CustomScrollView", "onInterceptTouchEvent: DOWN super false" );
            super.onTouchEvent(ev);
            break;

        case MotionEvent.ACTION_MOVE:
            return false; // redirect MotionEvents to ourself

        case MotionEvent.ACTION_CANCEL:
            // Log.i("CustomScrollView", "onInterceptTouchEvent: CANCEL super false" );
            super.onTouchEvent(ev);
            break;

        case MotionEvent.ACTION_UP:
            //Log.i("CustomScrollView", "onInterceptTouchEvent: UP super false" );
            return false;

        default:
            //Log.i("CustomScrollView", "onInterceptTouchEvent: " + action );
            break;
    

    return false;


@Override
public boolean onTouchEvent(MotionEvent ev) 
    super.onTouchEvent(ev);
    //Log.i("CustomScrollView", "onTouchEvent. action: " + ev.getAction() );
    return true;
  

【讨论】:

以上是关于用于在 Scrollview 中移动 Google 地图的 Android SupportMapFragment的主要内容,如果未能解决你的问题,请参考以下文章

图像尺寸不适用于 Page Control 和 ScrollView?

在 ScrollView 中移动子视图

在Google Analytics中合并网络数据和移动数据

unityscrollview自己移动

如何在滚动 contentView 之前向上移动 scrollview 的框架? (当 scrollView 从屏幕中间开始时)

使用 DragGesture 移动视图,同时在顶部有一个 ScrollView