Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set google map fragment inside scroll view

I want to set a Google map fragment inside vertical ScrollView, when I do the map does not zoom vertically, how can I override the touch event listener on MapView over the listener of ScrollView?

This is my xml code:

  <ScrollView  android:layout_height="wrap_content"     android:layout_width="fill_parent"      android:layout_above="@id/footer"     android:layout_below="@id/title_horizontalScrollView">     ///other things    <fragment      android:id="@+id/map"     android:layout_width="fill_parent"     android:layout_height="300dp"     class="com.google.android.gms.maps.SupportMapFragment"     />    //other things 
like image 398
Malo Avatar asked May 29 '15 08:05

Malo


People also ask

What is MapFragment?

public class MapFragment extends Fragment. A Map component in an app. This fragment is the simplest way to place a map in an application. It's a wrapper around a view of a map to automatically handle the necessary life cycle needs.

What is scroll view layout?

In Android, a ScrollView is a view group that is used to make vertically scrollable views. A scroll view contains a single direct child only. In order to place multiple views in the scroll view, one needs to make a view group(like LinearLayout) as a direct child and then we can define many views inside it.


1 Answers

Create a custom SupportMapFragment so that we can override its touch event:

WorkaroundMapFragment.java

import android.content.Context; import android.os.Bundle; import android.widget.FrameLayout;  import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup;  import com.google.android.gms.maps.SupportMapFragment;  public class WorkaroundMapFragment extends SupportMapFragment {     private OnTouchListener mListener;      @Override     public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle savedInstance) {         View layout = super.onCreateView(layoutInflater, viewGroup, savedInstance);          TouchableWrapper frameLayout = new TouchableWrapper(getActivity());          frameLayout.setBackgroundColor(getResources().getColor(android.R.color.transparent));          ((ViewGroup) layout).addView(frameLayout,                 new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));          return layout;     }      public void setListener(OnTouchListener listener) {         mListener = listener;     }      public interface OnTouchListener {         public abstract void onTouch();     }      public class TouchableWrapper extends FrameLayout {          public TouchableWrapper(Context context) {             super(context);         }          @Override         public boolean dispatchTouchEvent(MotionEvent event) {             switch (event.getAction()) {                 case MotionEvent.ACTION_DOWN:                     mListener.onTouch();                     break;                 case MotionEvent.ACTION_UP:                     mListener.onTouch();                     break;             }             return super.dispatchTouchEvent(event);         }     } } 

In this above class, we intercept the touch event by using TouchableWrapper.class that extends the FrameLayout. There is also a custom listener OnTouchListener to dispatch the touch event to the main activity named MyMapActivity that handles the map. When the touch event occurred, dispatchTouchEvent will be called and the listener mListener will handle it.

Then replace fragment class in xml with this class="packagename.WorkaroundMapFragment" instead of com.google.android.gms.maps.SupportMapFragment

Then in your activity initialize map as follows:

private GoogleMap mMap; 

inside onCreate do this:

  // check if we have got the googleMap already   if (mMap == null) {         SupportMapFragment mapFragment = (WorkaroundMapFragment) getChildFragmentManager().findFragmentById(R.id.map);         mapFragment.getMapAsync(new OnMapReadyCallback() {             Override                 public void onMapReady(GoogleMap googleMap)                     {                         mMap = googleMap;                         mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);                         mMap.getUiSettings().setZoomControlsEnabled(true);                              mScrollView = findViewById(R.id.scrollMap); //parent scrollview in xml, give your scrollview id value                         ((WorkaroundMapFragment) getChildFragmentManager().findFragmentById(R.id.map))                                 .setListener(new WorkaroundMapFragment.OnTouchListener() {                             @Override                             public void onTouch()                                 {                                         mScrollView.requestDisallowInterceptTouchEvent(true);                                 }                             });                     }         });     } 

Update: Answer updated to getMapAsync() based on answer by @javacoder123

like image 147
Alok Nair Avatar answered Oct 01 '22 08:10

Alok Nair