是否有Xamarin Mvvmcross Android共享元素导航示例?

Jon*_*rix 4 xamarin.android mvvmcross xamarin

我正在尝试使用Mvx在我的Xamarin Android应用程序中运行此动画/过渡.

我有卡片回收查看.点击卡片时,我现在打电话给:

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);
}
Run Code Online (Sandbox Code Playgroud)

我试图找到如何翻译这个java导航过渡到Xamarin与Mvvmcross:

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

startActivity(intent, options.toBundle());
Run Code Online (Sandbox Code Playgroud)

我知道在Mvx中您可以使用自定义演示者,但是如何抓住RecyclerView中的Tapped Card的ImageView,我想在新Activity上"转换"为新的ImageView?

谢谢!

.

Pla*_*d3r 9

是否有Xamarin Mvvmcross Android共享元素导航示例?

我不相信.

我知道在Mvx中您可以使用自定义演示者,但是如何抓住RecyclerView中的Tapped Card的ImageView,我想在新Activity上"转换"为新的ImageView?

我想到实现共享您想要转换的控件元素的最简单方法是使用视图标签和表示包ShowViewModel.

我建议对您的Adapter Click处理程序进行一些更改,以包含ViewHolder所选内容的视图(例如,使用EventArgs 参见GitHub repo).这样您就可以与之交互ImageView并设置一个标签,以后可以使用它来识别它.

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

    ViewModel.ShowDetails(imageView.Tag.ToString());
}
Run Code Online (Sandbox Code Playgroud)

然后在ViewModel中,通过presentationBundle发送该标记.

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

    ShowViewModel<DetailsViewModel>(presentationBundle: presentationBundle);
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个自定义演示者来拾取presentationBundle并处理通过转换创建新活动.自定义演示者,它使用标记来查找要转换的元素,并将其包含ActivityOptionsCompat在新活动的开头.这个例子是使用a MvxFragmentsPresenter但是如果你没有使用片段并且使用MvxAndroidViewPresenter解决方案几乎相同(覆盖显示而不需要构造函数).

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

GetTransitionNameSupport是一个扩展方法,只是在获取时进行平台API检查TransitionName.

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

    return string.Empty;
}
Run Code Online (Sandbox Code Playgroud)

最后一步是在您身上注册自定义演示者 Setup.cs

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

您可以在GitHub上查看演示此示例的repo.解决方案的设计使得演示者不必关心正在转换的控件的类型.控件仅需要用于标识它的标记.repo中的示例还允许指定要转换的多个控件元素(我不希望在上面的示例中包含更多复杂性).

共享元素演示