Xamarin,Android和Google地图:我无法上下移动地图(只能左右移动)



在一个页面中,我有一个ScrollView和一些标签内部,Google Maps在中间。在安卓系统中,当我试图向上或向下移动地图时,除了地图外,所有页面都会移动。为了显示地图,我使用Xamarin.Forms.GoogleMaps。我创建了自己的custommap来绘制路线。组件运行良好,我可以在iOSAndroid中看到地图,并且我可以移动地图。

我读了一些关于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 />
  1. 基本资源。Layout.xxxx"是布局文件的名称,即xxxx.xml
  2. layout.xml中的任何组件都可以具有例如,如果我们有

    <Button id="@+id/something"></Button>
    

    然后按钮的id是"something",我们可以从代码后面获得这个视图通过调用

    Button btn = (Button) v.findViewById(Resource.id.something);
    
  3. 基于您的代码的最佳解决方案,可以将视图.axml更改为rtc.axml

最新更新