2017-05-05 1 views
3

J'essaie d'obtenir ce animation/transition de travail dans mon application Xamarin Android avec Mvx.Existe-t-il un exemple de Navigation d'élément partagé Android Xvravel Mvvmcross?

J'ai une vue recyclée avec des cartes. Lorsque vous appuyez sur une carte, je l'appelle maintenant:

private void TimeLineAdapterOnItemClick(object sender, int position) 
{ 
    TimeLineAdapter ta = (TimeLineAdapter) sender; 
    var item = ta.Items[position]; 

    int photoNum = position + 1; 
    Toast.MakeText(Activity, "This is photo number " + photoNum, ToastLength.Short).Show(); 

    ViewModel.ShowDetails(item.Id); 
} 

J'essaie de savoir comment traduire cette navigation java avec transition vers Xamarin avec Mvvmcross:

ActivityOptionsCompat options = 
    ActivityOptionsCompat.MakeSceneTransitionAnimation(this, imageView, getString(R.string.activity_image_trans)); 

startActivity(intent, options.toBundle()); 

Je sais que, dans MVX vous pouvez-vous utiliser des présentateurs personnalisés, mais comment puis-je obtenir, par exemple, le ImageView de la carte engagée dans le RecyclerView que je voudrais «transformer» à la nouvelle ImageView sur la nouvelle activité?

Merci!

. Par exemple

Répondre

8

Y at-il un Xamarin Mvvmcross Android Shared Element Navigation exemple?

Je ne crois pas.

Je sais que, dans MVX vous pouvez utiliser les présentateurs personnalisés, mais comment dois-je mettre la main sur, par exemple, la ImageView de la carte taraudée au sein la RecyclerView que je voudrais « transformer » à le nouveau ImageView sur la nouvelle activité?

La meilleure façon que je peux penser à obtenir le partage des éléments de contrôle que vous souhaitez transition se fait par l'utilisation de view tags et un faisceau de présentation lors de l'utilisation ShowViewModel.

Je suggère de faire quelques changements à votre adaptateur gestionnaire Cliquez pour inclure le point de vue de l'ViewHolder étant sélectionné (Voir GitHub repo par exemple avec EventArgs). De cette façon, vous pouvez interagir avec le ImageView et définir une étiquette qui peut être utilisée plus tard pour l'identifier.

private void TimeLineAdapterOnItemClick(object sender, View e) 
{ 
    var imageView = e.FindViewById<ImageView>(Resource.Id.imageView); 
    imageView.Tag = "anim_image"; 

    ViewModel.ShowDetails(imageView.Tag.ToString()); 
} 

Ensuite, dans votre ViewModel, envoyez cette balise via un PresentationBundle.

public void ShowDetails(string animationTag) 
{ 
    var presentationBundle = new MvxBundle(new Dictionary<string, string> 
    { 
     ["Animate_Tag"] = animationTag 
    }); 

    ShowViewModel<DetailsViewModel>(presentationBundle: presentationBundle); 
} 

Ensuite, créez un présentateur personnalisé pour le pick-up presentationBundle et gérer la création d'une nouvelle activité avec la transition. Le présentateur personnalisé qui utilise la balise pour trouver l'élément que vous voulez faire la transition et inclure le ActivityOptionsCompat dans le démarrage de la nouvelle activité. Cet exemple utilise un MvxFragmentsPresenter mais si vous n'utilisez pas de fragments et en utilisant MvxAndroidViewPresenter la solution serait presque identique (Remplacer Show et aucun constructeur requis).

public class SharedElementFragmentsPresenter : MvxFragmentsPresenter 
{ 
    public SharedElementFragmentsPresenter(IEnumerable<Assembly> AndroidViewAssemblies) 
     : base(AndroidViewAssemblies) 
    { 
    } 

    protected override void ShowActivity(MvxViewModelRequest request, MvxViewModelRequest fragmentRequest = null) 
    { 
     if (InterceptPresenter(request)) 
      return; 

     Show(request, fragmentRequest); 
    } 

    private bool InterceptPresenter(MvxViewModelRequest request) 
    { 
     if ((request.PresentationValues?.ContainsKey("Animate_Tag") ?? false) 
      && request.PresentationValues.TryGetValue("Animate_Tag", out var controlTag)) 
     { 
      var intent = CreateIntentForRequest(request); 

      var control = Activity.FindViewById(Android.Resource.Id.Content).FindViewWithTag(controlTag); 
      control.Tag = null; 

      var transitionName = control.GetTransitionNameSupport(); 
      if (string.IsNullOrEmpty(transitionName)) 
      { 
       Mvx.Warning($"A {nameof(transitionName)} is required in order to animate a control."); 
       return false; 
      } 

      var activityOptions = ActivityOptionsCompat.MakeSceneTransitionAnimation(Activity, control, transitionName); 

      Activity.StartActivity(intent, activityOptions.ToBundle()); 
      return true; 
     } 

     return false; 
    } 
} 

GetTransitionNameSupport est une méthode d'extension qui fait juste une vérification de l'API de la plate-forme lors de l'obtention du TransitionName.

public static string GetTransitionNameSupport(this ImageView imageView) 
{ 
    if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) 
     return imageView.TransitionName; 

    return string.Empty; 
} 

La dernière étape serait d'inscrire le présentateur personnalisé en vous Setup.cs

protected override IMvxAndroidViewPresenter CreateViewPresenter() 
{ 
    var mvxPresenter = new SharedElementFragmentsPresenter(AndroidViewAssemblies); 
    Mvx.RegisterSingleton<IMvxAndroidViewPresenter>(mvxPresenter); 
    return mvxPresenter; 
} 

Vous pouvez vérifier l'repo on GitHub qui démontre cet exemple. La solution est conçue pour que le présentateur ne se soucie pas du type de contrôle en cours de transition. Un contrôle nécessite uniquement une étiquette utilisée pour l'identifier. L'exemple dans le repo permet également de spécifier plusieurs éléments de contrôle que vous voulez faire passer (je ne voulais pas inclure plus de complexité dans l'exemple ci-dessus).

Shared Element Demo

+0

Merci beaucoup pour passer ce laps de temps et d'efforts pour que cela soit clair pour moi et la communauté open-source MVX. – JonHendrix

+1

@JonHendrix, pas de problème. J'avais toujours voulu essayer cette animation, et quand j'ai lu votre question, j'ai pensé que je pourrais aussi bien l'essayer maintenant :) – Plac3Hold3r

+1

@ Plac3Hold3r Vous pourriez vouloir regarder https://github.com/MvvmCross/MvvmCross/pull/2022 qui ajoute un support pour cela. – Martijn00