Using MapFragment inside ScrollView
06 Nov 2014 | Xamarin.Android MapsI found a nice little code snippet, Lorensius Londa posted on his blog, for Java Android, which overlays the MapFragment with a FrameLayout and using the FrameLayout touch event. Using this exact technique help me achieve my goal as well. Here is the code I used.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TouchableMapFragment : MapFragment | |
{ | |
public event EventHandler TouchDown; | |
public event EventHandler TouchUp; | |
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) | |
{ | |
var root = base.OnCreateView(inflater, container, savedInstanceState); | |
var wrapper = new TouchableWrapper(Activity); | |
wrapper.SetBackgroundColor(Resources.GetColor(Android.Resource.Color.Transparent)); | |
((ViewGroup) root).AddView(wrapper, | |
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent)); | |
wrapper.TouchUp = () => | |
{ | |
if (TouchUp != null) | |
TouchUp(this, EventArgs.Empty); | |
}; | |
wrapper.TouchDown = () => | |
{ | |
if (TouchDown != null) | |
TouchDown(this, EventArgs.Empty); | |
}; | |
return root; | |
} | |
class TouchableWrapper : FrameLayout | |
{ | |
public Action TouchDown; | |
public Action TouchUp; | |
#region ctors | |
protected TouchableWrapper(IntPtr javaReference, JniHandleOwnership transfer) | |
: base(javaReference, transfer) {} | |
public TouchableWrapper(Context context) | |
: this(context, null) {} | |
public TouchableWrapper(Context context, IAttributeSet attrs) | |
: this(context, attrs, 0) {} | |
public TouchableWrapper(Context context, IAttributeSet attrs, int defStyle) | |
: base(context, attrs, defStyle) { } | |
#endregion | |
public override bool DispatchTouchEvent(MotionEvent e) | |
{ | |
switch (e.Action) | |
{ | |
case MotionEventActions.Down: | |
if (TouchDown != null) | |
TouchDown(); | |
break; | |
case MotionEventActions.Cancel: | |
case MotionEventActions.Up: | |
if (TouchUp != null) | |
TouchUp(); | |
break; | |
} | |
return base.DispatchTouchEvent(e); | |
} | |
} | |
} |
The Fragment is used as follows in a AXML layout.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:id="@+id/scroll"> | |
<LinearLayout | |
android:orientation="horizontal" | |
android:layout_width="wrap_content" | |
android:layout_height="match_parent"> | |
<fragment | |
android:id="@+id/map" | |
android:layout_width="600dp" | |
android:layout_height="match_parent" | |
android:name="my.awesome.namespace.TouchableMapFragment" /> | |
</LinearLayout> | |
</HorizontalScrollView> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class MyActivity : Activity | |
{ | |
private GoogleMap _map; | |
private HorizontalScrollView _hsv; | |
protected override void OnCreate(Bundle bundle) | |
{ | |
base.OnCreate(bundle); | |
SetContentView(Resource.Layout.rtc); | |
_hsv = FindViewById<HorizontalScrollView>(Resource.Id.scroll); | |
SetupMapIfNeeded(); | |
} | |
private void SetupMapIfNeeded() | |
{ | |
if (null != _map) return; | |
var frag = FragmentManager.FindFragmentById<TouchableMapFragment>(Resource.Id.map); | |
if (frag != null) | |
{ | |
frag.TouchUp += (sender, args) => _hsv.RequestDisallowInterceptTouchEvent(false); | |
frag.TouchDown += (sender, args) => _hsv.RequestDisallowInterceptTouchEvent(true); | |
_map = frag.Map; | |
if (_map == null) return; // will probably not happen | |
// do stuff to _map here, such as adding overlays etc. | |
} | |
} | |
} |