r3dm4n
r3dm4n

Reputation: 1215

Disable scrolling when scaling with Google Maps API

When I try to pan the google map, the CoordinatorLayout scrolls down, and of course I want to pan the map instead. If I hold outside the Map and then try to pan then it works perfectly, but that wouldn't be a very good end user experience.

The OnTouchListener fixes part of the problem... but only if I pan horizontally. The moment my finger goes up or down it stops panning the map. How can I fix this?

public class HomeFragment extends Fragment {

private TextView aboutTxt;
private SupportMapFragment mSupportMapFragment;
private GoogleMap mMap;
public HomeFragment() {
    // Required empty public constructor
}


// TODO: Rename and change types and number of parameters
public static HomeFragment newInstance() {
    HomeFragment fragment = new HomeFragment();

    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {

    }
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_home, container, false);


           view.setOnTouchListener(new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {



            if (event.getAction()==MotionEvent.ACTION_DOWN) {

                Log.e(TAG,"Down");
                return true;
            }

            if (event.getAction()==MotionEvent.ACTION_MOVE){

                Log.e(TAG,"Move");
                return true;

            }
            if (event.getAction()==MotionEvent.ACTION_UP){

                Log.e(TAG,"Up");
                return true;
            }


            return false;
        }
           });



    mSupportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
    if (mSupportMapFragment == null) {
        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        mSupportMapFragment = SupportMapFragment.newInstance();
        fragmentTransaction.replace(R.id.map, mSupportMapFragment).commit();
    }

    if (mSupportMapFragment != null) {
        mSupportMapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                if (googleMap != null) {

                    mMap = googleMap;
                    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

                    // Add a marker in Sydney and move the camera
                    LatLng myMap = new LatLng(xx.xxxx, xx.xxxx);
                    mMap.addMarker(new MarkerOptions().position(gradiMap).title("My marker));
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myMap, 17));

                }


            }
        });
    }

XML

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

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/main.collapsing"
        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">

        <FrameLayout
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_collapseMode="parallax" />


        <android.support.v7.widget.Toolbar
            android:id="@+id/main.toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.CollapsingToolbarLayout>

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

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <TextView
        android:id="@+id/aboutTxt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:lineSpacingExtra="8dp"
        android:padding="@dimen/activity_horizontal_margin"
        android:textColor="@color/colorBlack"
        android:textSize="17sp" />

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

<android.support.design.widget.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/activity_horizontal_margin"
    android:src="@drawable/whitestar"
    app:layout_anchor="@id/main.appbar"
    app:layout_anchorGravity="bottom|right|end" />

Upvotes: 0

Views: 1404

Answers (2)

r3dm4n
r3dm4n

Reputation: 1215

Found the answer here. Like Teimoor Alam Khan said, just make a custom class and use that.

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;
  }
}

XML:

<com.app.ui.views.CustomScrollView
android:id="@+id/scrollView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:orientation="vertical">
</com.app.ui.views.CustomScrollView>

Upvotes: 0

LukeWaggoner
LukeWaggoner

Reputation: 8909

I think you're looking for OnInterceptTouchEvent. You can set it on your CoordinatorLayout and be able to determine whether it should consume the event itself, or pass it to it's child views.

You'll need to extend CoordinatorLayout and override onInterceptTouchEvent(MotionEvent event) and do the following:

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            return false;
            break;
        case MotionEvent.ACTION_MOVE:
            return false;
            break;
        default:
            return true;
            break;
    }
}

Upvotes: 2

Related Questions