2017-10-10 98 views
0

在頁面我有一個ScrollView,裏面有一些標籤,中間有一個Google Maps。在Android中,當我嘗試向上或向下移動地圖時,所有頁面都會移動,但地圖會移動。要顯示我正在使用的地圖Xamarin.Forms.GoogleMaps。我創建了自己的custommap來繪製路線。該組件運行良好,我可以看到地圖iOSAndroid,我可以移動地圖。Xamarin,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. 
    } 
    } 
} 

有幾個誤區:

  • 如何解決Android的問題妥善移動地圖?
  • SetContentView(Resource.Layout.rtc);什麼是rtc?
  • Resource.Id.map不存在

在我的情況,我有iOS和Android項目PCL解決方案。在iOS中一切都很好。唯一的問題是Android。我該如何解決這個問題?

有什麼建議嗎?謝謝。

+0

這是很難說什麼是「RTC」,但基本上Resource.Layout.xxxx的 xxxx」是的名稱佈局文件,例如xxxx.xml ,layout.xml中的任何組件都可以具有「id」屬性,例如,如果我們有一個

+0

來從代碼背後獲得這個視圖,謝謝@GaneshCauda我明白了,我的問題與我找到的代碼有關,我無法理解我可以如何在Xamarin.Form中使用它s' – Enrico

+0

看你的代碼,最好的可能是用「view」或者反過來改變「rtc」(「view.axml」用「rtc.axml」 –

回答

1

我的問題是關係到我發現的代碼。我不明白我如何在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 /> 
+0

謝謝!它工作完美! – Enrico

+0

'_map = frag.Map;'不存在 – Enrico

0
  1. 基本上Resource.Layout.xxxx的xxxx」是佈局文件的名稱,即xxxx.xml
  2. 內部layout.xml任何組件都可以有一個‘id’屬性 例如,如果我們有一個

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

    那麼按鈕的ID是「東西」,我們可以通過調用

    Button btn = (Button) v.findViewById(Resource.id.something); 
    
  3. 擺脫代碼這個觀點背後
  4. 最佳的解決方案基於您的代碼,也許改變view.axmlrtc.axml