在一个页面中,我有一个ScrollView
和一些标签内部,Google Maps
在中间。在安卓系统中,当我试图向上或向下移动地图时,除了地图外,所有页面都会移动。为了显示地图,我使用Xamarin.Forms.GoogleMaps。我创建了自己的custommap
来绘制路线。组件运行良好,我可以在iOS
和Android
中看到地图,并且我可以移动地图。
我读了一些关于Stackoverflow的帖子和这篇帖子,但这些家伙总是一个活动,这个项目是原生的。
我创建了:
TouchableMapFragment
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);
}
}
}
view.xaml
<?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>
活动.cs
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.
}
}
}
有几个错误:
- 如何解决安卓系统正确移动地图的问题
- SetContentView(Resource.Layout.rtc);什么是rtc
- Resource.Id.map不存在
就我而言,我有一个适用于iOS和Android项目的PCL解决方案。在iOS中,一切都很好。唯一的问题是安卓系统。如何解决此问题?
有什么建议吗?谢谢
我的问题与我找到的代码有关。我不明白如何在Xamarin中使用它。表格
在XF框架中,我们只有一个Activity
,意味着默认的MainAcitivty
,所有视图都基于此MainAcitivty
显示,如果您想在PCL中显示来自客户端Android项目的自定义视图,通常我们使用Custom Renderer
来创建视图渲染器,对于您的情况,您的view.axml
是客户端Android项目中的布局资源,然后应该在渲染器中实现该视图的逻辑代码。
首先在PCL中创建View
的子类,这样它就可以像普通XF控件一样使用:
public class ScrollViewWithMap:View
{
}
然后在Android客户端项目中,将view.axml放在Resources/layout
文件夹下,并一起创建它的渲染器:
[assembly: ExportRenderer(typeof(ScrollViewWithMap), typeof(ScrollViewWithMapRenderer))]
namespace YOURNAMESPACE.Droid
{
public class ScrollViewWithMapRenderer : ViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var context = Xamarin.Forms.Forms.Context;
LayoutInflater minflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
var view = minflater.Inflate(Resource.Layout.view, this, false);
SetNativeControl(view);
}
}
}
}
然后您可以将逻辑代码从MyActivity
移动到此ScrollViewWithMapRenderer
,例如:
public class ScrollViewWithMapRenderer : ViewRenderer
{
private GoogleMap _map;
private HorizontalScrollView _hsv;
private Context context = Xamarin.Forms.Forms.Context;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (Control == null)
{
LayoutInflater minflater = context.GetSystemService(Context.LayoutInflaterService) as LayoutInflater;
var view = minflater.Inflate(Resource.Layout.view, this, false);
_hsv = view.FindViewById<HorizontalScrollView>(Resource.Id.scroll);
SetNativeControl(view);
SetupMapIfNeeded();
}
}
private void SetupMapIfNeeded()
{
if (null != _map) return;
var frag = ((Activity)context).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.
}
}
}
我在你的TouchableMapFragment
中找不到属性Map
,我认为你的代码不完整,你应该能够解决这个问题。顺便说一下,代码TouchableMapFragment
也应该放在android客户端项目中。
最后,我们可以在PCL中使用这个ScrollViewWithMap
,例如:
<local:ScrollViewWithMap />
- 基本资源。Layout.xxxx"是布局文件的名称,即xxxx.xml
-
layout.xml中的任何组件都可以具有例如,如果我们有
<Button id="@+id/something"></Button>
然后按钮的id是"something",我们可以从代码后面获得这个视图通过调用
Button btn = (Button) v.findViewById(Resource.id.something);
-
基于您的代码的最佳解决方案,可以将视图.axml更改为rtc.axml