Google 带有 CollapsingToolbar 和 NestedScrollView 的地图

Google Map with CollapsingToolbar and NestedScrollView

我正在开发像 UBER 这样的应用程序。自定义标记的第一次滚动在地图上运行良好。之后我像 UBER 一样添加了 NestedScrollView。但是地图滚动手势与 AppBar 滚动行为冲突。 我不知道该怎么办,请帮帮我。

截图

这是我的代码。

home_fragment.xml

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

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="460dp"
    android:fitsSystemWindows="true"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:expandedTitleMarginEnd="64dp"
        app:expandedTitleMarginStart="48dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

        <!-- Map Layout starts here -->
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_collapseMode="parallax">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <fragment
                    android:id="@+id/map"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    class="com.anuj.retrofitparsing.customClasses.MySupportMapFragment"></fragment>


                <ImageView
                    android:id="@+id/mylocation"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_alignParentRight="true"
                    android:layout_margin="@dimen/activity_margin_16"
                    android:padding="@dimen/activity_margin_10"
                    android:src="@drawable/mylocation" />

                <LinearLayout
                    android:id="@+id/locationMarker"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_gravity="center"
                    android:layout_marginBottom="30dp"
                    android:gravity="center"
                    android:orientation="vertical">

                    <TextView
                        android:id="@+id/locationMarkertext"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:background="@drawable/setlocation_bg"
                        android:gravity="center"
                        android:minWidth="180dp"
                        android:padding="@dimen/activity_margin_5"
                        android:paddingLeft="2dp"
                        android:paddingRight="2dp"
                        android:text=" Set your Location "
                        android:textColor="@color/white" />

                    <ImageView
                        android:id="@+id/imageView1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/add_marker" />
                </LinearLayout>
            </RelativeLayout>


            <LinearLayout
                android:id="@+id/search_layout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="top"
                android:layout_margin="@dimen/activity_margin_16"
                android:background="@drawable/searchbar_bg"
                android:orientation="vertical"
                android:padding="@dimen/activity_margin_5">

                <TextView
                    android:id="@+id/textView1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:text="Selected Location"
                    android:textAppearance="?android:attr/textAppearanceSmall"
                    android:textColor="#28b54c"
                    android:textSize="@dimen/text_size" />

                <TextView
                    android:id="@+id/adressText"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="10dp"
                    android:ellipsize="end"
                    android:singleLine="true"
                    android:text="Getting location"
                    android:textColor="@color/app_textcolor"
                    android:textSize="@dimen/text_size_small" />
            </LinearLayout>
        </FrameLayout>
        <!-- Map Layout Ends here -->

    </android.support.design.widget.CollapsingToolbarLayout>

</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.NestedScrollView
    android:id="@+id/nScrollView"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    android:layout_alignParentBottom="true"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

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

TouchableWrapper.java

public class TouchableWrapper extends FrameLayout {
    public TouchableWrapper(Context context) {
        super(context);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                HomeFragment.mMapIsTouched = true;
                break;

            case MotionEvent.ACTION_UP:
                HomeFragment.mMapIsTouched = false;
                break;
        }
        return super.dispatchTouchEvent(event);
    }
}

MySupportMapFragment

public class MySupportMapFragment extends SupportMapFragment {
    public View mOriginalContentView;
    public TouchableWrapper mTouchView;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
        mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
        mTouchView = new TouchableWrapper(getActivity());
        mTouchView.addView(mOriginalContentView);
        return mTouchView;
    }

    @Override
    public View getView() {
        return mOriginalContentView;
    }
}

HomeFragment

googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {

            @Override
            public void onCameraChange(CameraPosition arg0) {
                // TODO Auto-generated method stub
                if (!mMapIsTouched) {
                    // Show Outer layout
                    CommonMethods.getInstance().e("","User Is not touching MAP");
                    googleMap.getUiSettings().setAllGesturesEnabled(true);
                }
                else{
                    // Hide Outer Layout
                    CommonMethods.getInstance().e("", "User Is touching MAP");
                    googleMap.getUiSettings().setAllGesturesEnabled(false);
                }

            }
        });

经过长时间的搜索,我发现设计库中存在错误,并且已经reported

那里提到

Scrollable containers in an AppBarLayout have never been officially supported.

If the next release have a look at AppBarLayout.Behavior.DragCallback which allows you to disable the drag handling if you need.

DragCallback 方法停止应用栏布局内容中的拖动效果,并且 NestedScrollView 工作正常。

AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);
    CoordinatorLayout.LayoutParams params = 
            (CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams();
    AppBarLayout.Behavior behavior = new AppBarLayout.Behavior();
    behavior.setDragCallback(new AppBarLayout.Behavior.DragCallback() {
        @Override
        public boolean canDrag(AppBarLayout appBarLayout) {
            return false;
        }
    });