NestedScrollView 内的 MapView 滚动不流畅

MapView inside NestedScrollView not scrolling smooth

我对 NestedScroollView 中的 MapView 有疑问。 我的 Google 地图显示正确,但是当我尝试滚动地图时它不起作用。我不知道如何解决这个问题。谁能帮我?谢谢!

这是我的代码: Dog_view.xml

...
<android.support.v4.widget.NestedScrollView
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/nestedScroll"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <include layout="@layout/dog_view_layout"
        android:layout_height="match_parent"
        android:layout_width="match_parent"/>

</android.support.v4.widget.NestedScrollView>

dog_view_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:background="#000"
    android:layout_height="wrap_content"
    android:paddingTop="20dp">
    <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

DogFragment

...
    MapView mMapView;
    private GoogleMap googleMap;


    public DogFragment(){

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.dog_view, container, false);
        this.dog = getArguments().getParcelable("data");
        mMapView = (MapView) rootView.findViewById(R.id.mapView);
        mMapView.onCreate(savedInstanceState);
        mMapView.onResume(); // needed to get the map to display immediately
        try {
            MapsInitializer.initialize(getActivity().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }

        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {
                googleMap = mMap;
                googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
                googleMap.setMyLocationEnabled(true);
            }
        });
        setLayout(rootView);
        return rootView;
    }
.....
}

我遇到了同样的问题。这是解决方案。我制作了一个自定义 MapView 并像这样覆盖 onTouchEvent()。

 @Override
public boolean onTouchEvent(MotionEvent ev) {
    int action = ev.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        // Disallow ScrollView to intercept touch events.
        this.getParent().requestDisallowInterceptTouchEvent(true);
        break;

    case MotionEvent.ACTION_UP:
        // Allow ScrollView to intercept touch events.
        this.getParent().requestDisallowInterceptTouchEvent(false);
        break;
    }

    // Handle MapView's touch events.
    super.onTouchEvent(ev);
    return true;
}

您必须创建自定义 MapView。按照下面提供的代码片段进行操作

public class AppMapView extends MapView {

    public AppMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_UP:
               System.out.println("unlocked");
               this.getParent().requestDisallowInterceptTouchEvent(false);
               break;

            case MotionEvent.ACTION_DOWN:
               System.out.println("locked");
               this.getParent().requestDisallowInterceptTouchEvent(true);
               break;
       }
       return super.dispatchTouchEvent(ev);
   }
}

在 XML 中遵循以下代码:

<com.hantash.nadeem.custom_views.AppMapView
   android:id="@+id/map_ride_route"
   android:layout_width="match_parent"
   android:layout_height="220dp"
   android:layout_margin="10dp"/>

下面是找Kotlin的CustomMapView代码

class CustomMapView(context: Context, attributeSet: AttributeSet) : MapView(context, attributeSet) {

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    when (ev.action) {
        MotionEvent.ACTION_UP -> parent.requestDisallowInterceptTouchEvent(false)
        MotionEvent.ACTION_DOWN -> parent.requestDisallowInterceptTouchEvent(true)
    }
    return super.dispatchTouchEvent(ev)
 } 
}