在一个页面中,我有一个ScrollView
,里面有一些标签,中间有一个Google Maps
。在Android中,当我尝试向上或向下移动地图时,所有页面都会移动但是地图。要使用Xamarin.Forms.GoogleMaps显示地图,请执行此操作。我创建了自己的custommap
来绘制路线。该组件运行良好,我可以在iOS
和Android
中查看地图,我可以移动地图。
我在Stackoverflow和this post上阅读了一些帖子,但是这些人总是一个活动,项目是原生的。
我创建了:
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>
Activity.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.
}
}
}
有几个错误:
就我而言,我有一个包含iOS和Android项目的PCL解决方案。在iOS中一切都很好。唯一的问题是Android。我该如何解决这个问题?
有什么建议吗?感谢。
答案 0 :(得分:1)
我的问题与我找到的代码有关。我无法理解如何在Xamarin.Forms中使用它
在XF框架中,我们只有一个Activity
,表示默认MainAcitivty
,所有视图都是根据此MainAcitivty
显示的,您希望从客户端Android显示自定义视图在PCL中的项目,通常我们使用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.
}
}
}
我在Map
中找不到属性TouchableMapFragment
,我认为您的代码不完整,您应该能够解决此问题。顺便说一下,代码TouchableMapFragment
也应放在android客户端项目中。
最后,我们可以在PCL中使用此ScrollViewWithMap
,例如:
<local:ScrollViewWithMap />
答案 1 :(得分:0)
layout.xml中的任何组件都可以有一个&#34; id&#34;属性 例如,如果我们有一个
<Button id="@+id/something"></Button>
然后按钮的ID是&#34;&#34;我们可以从后面的代码中获取此视图 通过调用
Button btn = (Button) v.findViewById(Resource.id.something);
基于您的代码的最佳解决方案,可能会将 view.axml 更改为 rtc.axml