嵌套在NestedScrollView中的MapView无法滚动

9
在XML中像这样填充我的Mapview:
<android.support.v4.widget.NestedScrollView
        android:id="@+id/sv_offers"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="56dp"
        android:visibility="gone"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <com.xys.widgets.CustomMapView
                android:id="@+id/mapView"
                android:layout_width="match_parent"
                android:layout_height="125dp"/>


        </LinearLayout>

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

我已经按照以下方式实现了自定义地图视图:-
public class CustomMapView extends MapView {

    private ViewParent mViewParent;

    public CustomMapView(Context context) {
        super(context);
    }

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

    public CustomMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setViewParent(@Nullable final ViewParent viewParent) { //any ViewGroup
        mViewParent = viewParent;
    }

    public CustomMapView(Context context, GoogleMapOptions options) {
        super(context, options);
    }

    @Override
    public boolean onInterceptTouchEvent(final MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if (null == mViewParent) {
                    getParent().requestDisallowInterceptTouchEvent(true);
                    Timber.d("Inside if of action down");
                } else {
                    mViewParent.requestDisallowInterceptTouchEvent(true);
                    Timber.d("Inside else of action down");
                }
                break;
            case MotionEvent.ACTION_UP:
                if (null == mViewParent) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                    Timber.d("Inside if of action up");
                } else {
                    mViewParent.requestDisallowInterceptTouchEvent(false);
                    Timber.d("Inside else of action up");
                }
                break;
            default:
                break;
        }

        return super.onInterceptTouchEvent(event);
    }
}

在我的Activity的onCreate()方法中初始化了我的地图视图。
mapView = (CustomMapView) findViewById(R.id.mapView);
        mapView.onCreate(savedInstanceState);
        GoogleMap googleMap = mapView.getMap();

        googleMap.setMyLocationEnabled(false);
        googleMap.getUiSettings().setMyLocationButtonEnabled(false);
        googleMap.getUiSettings().setCompassEnabled(false);
        googleMap.getUiSettings().setAllGesturesEnabled(false);

        mapView.setViewParent(nestedScrollContainer);

我有一个嵌套的scrollView,其中nestedScrollContainer是它的容器。在stackoverflow上尝试了许多解决方法,但好像没有办法解决滚动问题。希望能得到帮助!谢谢。


你的 CustomMapView 的目的是什么? - Androiderson
CustomMapView就是MapView的扩展,具有自定义触摸拦截器,以便在ScrollView内启用滚动。 - williamj949
3
我遇到了同样的问题,但我注意到如果我将mapView.onCreate(savedInstanceState); 的调用推迟500毫秒,例如在我的片段中onActivityCreated调用之后,它就可以正常工作。到目前为止,我还没有找到一个干净的解决方法来解决这个问题。 - Bibu
请检查这个链接并让我知道是否有任何疑问。 - Saamzzz
3个回答

8

在你的代码中,MapView 位于 NestedScrollView--> LinearLayout--> com.xys.widgets.CustomMapView 这两级层次结构中。

因此,在你的情况下,可以像下面这样访问 NestedScrollView:

getParent().getParent().requestDisallowInterceptTouchEvent(true); 

将这一行代码

getParent().requestDisallowInterceptTouchEvent(true);

改为以下内容:

getParent().getParent().requestDisallowInterceptTouchEvent(true);

以下是您的情况的完整代码。
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.xys.widgets.CustomMapView
            android:id="@+id/mapView"
            android:layout_width="match_parent"
            android:layout_height="125dp"/>


    </LinearLayout>

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

`

public class CustomMapView extends MapView {

        private ViewParent mViewParent;

        public CustomMapView(Context context) {
            super(context);
        }

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

        public CustomMapView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }

        public void setViewParent(@Nullable final ViewParent viewParent) { //any ViewGroup
            mViewParent = viewParent;
        }

        public CustomMapView(Context context, GoogleMapOptions options) {
            super(context, options);
        }

        @Override
        public boolean onInterceptTouchEvent(final MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:

                        getParent().getParent().requestDisallowInterceptTouchEvent(true);
                        Timber.d("Inside if of action down");
                    break;
                case MotionEvent.ACTION_UP:

                        getParent().getParent().requestDisallowInterceptTouchEvent(false);
                        Timber.d("Inside if of action up");

                    break;
                default:
                    break;
            }

            return super.onInterceptTouchEvent(event);
        }
    }

1
我找到了一个解决方案 -
class CustomMapView(context: Context, attrs: AttributeSet?): MapView(context, attrs) {

override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
    this.performClick()
    when (ev.action) {
        MotionEvent.ACTION_DOWN ->         // Disallow ScrollView to intercept touch events.
            this.parent.requestDisallowInterceptTouchEvent(true)
        MotionEvent.ACTION_UP ->         // Allow ScrollView to intercept touch events.
            this.parent.requestDisallowInterceptTouchEvent(false)
    }

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

}


0

在NestedScrollView内部几乎可以获得正方形的MapView。

    //Fix map height
    ViewGroup.LayoutParams lp = mapView.getLayoutParams();
    DisplayMetrics metrics = getResources().getDisplayMetrics();
    lp.height = metrics.widthPixels;
    mapView.setLayoutParams(lp);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接