2017-10-10 7 views
0

Dans une page, j'ai un ScrollView et à l'intérieur des étiquettes et un Google Maps au milieu. Dans Android, lorsque j'essaie de déplacer la carte vers le haut ou vers le bas, toutes les pages sont déplacées à l'exception de la carte. Pour afficher la carte, j'utilise Xamarin.Forms.GoogleMaps. J'ai créé mon propre custommap pour dessiner un itinéraire. Le composant fonctionne bien, je peux voir la carte en iOS et Android et je peux déplacer la carte.Xamarin, Android et Google Maps: Je ne peux pas déplacer la carte de haut en bas (uniquement à gauche et à droite)

J'ai lu quelques messages sur Stackoverflow et this post mais toujours les gars sont une activité et le projet est natif.

J'ai créé:

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. 
    } 
    } 
} 

Il y a quelques erreurs:

  • Comment puis-je résoudre le problème pour Android pour déplacer la carte correctement?
  • SetContentView (Resource.Layout.rtc); qu'est-ce que rtc?
  • Resource.Id.map n'existe pas

Dans mon cas, j'ai une solution PCL avec des projets iOS et Android. Dans iOS, tout va bien. Le seul problème est pour Android. Comment puis-je résoudre ce problème?

Un conseil? Merci.

+0

il est difficile de dire ce qui est « pac », mais Resource.Layout.xxxx essentiellement le xxxx » est le nom du fichier de mise en page, par exemple xxxx.xml et tout composant à l'intérieur layout.xml peut avoir un attribut "id" par exemple si nous avons un alors l'identifiant du bouton est "quelque chose "et nous pouvons obtenir cette vue du code derrière en appelant Button btn = (Button) Resource.id.something; –

+0

Merci @GaneshCauda J'ai compris cela.Ma question est liée au code que j'ai trouvé.Je ne peux pas comprendre comment je peux utilisez-le dans 'Xamarin.Form s' – Enrico

+0

en regardant votre code, la meilleure possibilité est peut-être de changer le "rtc" avec "vue" ou vice versa ("view.axml" avec "rtc.axml" –

Répondre

1

Ma question est liée au code que j'ai trouvé. Je ne peux pas comprendre comment je peux l'utiliser dans Xamarin.Formulaires

Dans le cadre XF, nous avons un seul Activity, signifie la valeur par défaut MainAcitivty, toutes les vues sont affichées en fonction de cette MainAcitivty, il vous voulez montrer une vue personnalisée du projet Android client dans PCL, généralement nous utilisons Custom Renderer Pour créer une vue Renderer, pour votre cas, votre view.axml est la ressource de mise en page dans le projet client Android, alors vous devez implémenter le code logique pour cette vue dans le moteur de rendu.

d'abord créer une sous-classe de View en PCL de sorte qu'il peut être utilisé comme normale le contrôle XF:

public class ScrollViewWithMap:View 
{ 
} 

Ensuite, dans le projet de client Android placer votre view.axml dans le dossier Resources/layout et créent ensemble il est renderer:

[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); 
      } 
     } 
    } 
} 

Ensuite, vous pouvez déplacer le code logique de votre MyActivity à ce ScrollViewWithMapRenderer par exemple:

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. 
     } 
    } 
} 

Je ne pouvais pas trouver une propriété Map dans votre TouchableMapFragment, je pense que vous codez incomplète et vous devriez être en mesure de résoudre ce problème. Par ailleurs, le code TouchableMapFragment devrait également être placé dans le projet client android.

Enfin, nous pouvons utiliser ce ScrollViewWithMap dans PCL par exemple comme ceci:

<local:ScrollViewWithMap /> 
+0

Merci! Cela fonctionne parfaitement! – Enrico

+0

'_map = frag.Map;' n'existe pas – Enrico

0
  1. Fondamentalement Resource.Layout.xxxx xxxx » est le nom du fichier de mise en page, à savoir xxxx.xml
  2. Tout composant à l'intérieur layout.xml peut avoir un « attribut id » pour exemple, si nous avons un

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

    alors l'identifiant du bouton est « quelque chose » et nous pouvons obtenir ce point de vue à partir du code derrière en appelant

    Button btn = (Button) v.findViewById(Resource.id.something); 
    
  3. La meilleure solution possible en fonction de votre code, peut-être changer le view.axml à rtc.axml