簡體   English   中英

Xamarin Android 使用 MvvmCross 和 FFImageLoading 的可見性綁定問題

[英]Xamarin Android visibility binding issue using MvvmCross and FFImageLoading

為了在我的應用程序(使用 Mvx 和 FFimageLoading 的 Xamarin AndroidX)中創建動畫加載程序 UI 控件,我創建了一個繼承自MvxCachedImageView的自定義控件。 然后我應用我的 animation 如下:

public class LoaderView : MvxCachedImageView
    {
        protected LoaderView(IntPtr javaReference, JniHandleOwnership transfer)
            : base(javaReference, transfer)
        {
            Create();
        }

        public LoaderView(Context context)
            : base(context)
        {
            Create();
        }

        public LoaderView(Context context, IAttributeSet attrs)
            : base(context, attrs)
        {
            Create();
        }

        private void Create()
        {
            if (Context == null)
                return;

            ImageService.Instance.LoadCompiledResource("loader_indicator")
                .Into(this);

            ApplyRotation();

            StartAnimation(Animation);
        }
        
        private void ApplyRotation()
        {
            var rotation = new RotateAnimation(
                0,
                360,
                Dimension.RelativeToSelf,
                0.5f,
                Dimension.RelativeToSelf,
                0.5f)
            {
                Duration = 1200,
                Interpolator = new DecelerateInterpolator(1.25f),
                RepeatCount = Animation.Infinite
            };

            Animation = rotation;
        }
    }

注意loader_indicator是一個 gif 文件

在我嘗試將其可見性屬性綁定到“經典” IsLoading BaseViewModel 的屬性之前,此控件一直正常工作,如下所示:

var set = CreateBindingSet();
set.Bind(loader).For(v => v.Visibility).To(vm => vm.IsLoading)
                .WithConversion<MvxVisibilityValueConverter>();
set.Apply();

如上所述執行應用程序, Visibility綁定和 gif animation隨機工作:有時會,有時不會; 有時, RotateAnimation正在工作,但針對的是父元素而不是自身 - 在糟糕的情況下,您的圖標會進入頁面..

做不同的測試我明白如果我刪除ApplyRotationStartAnimation控件會正確顯示和binded

這似乎是某個地方的線程問題。 有沒有人見過並(可能)解決了這個問題?

編輯: Cheesebaron anwser 給了我一個正確的提示,所以我改變了LoaderView實現如下,它實際上解決了這個問題:

public class LoaderView : MvxCachedImageView
{
    private Animation _animation;

    protected LoaderView(IntPtr javaReference, JniHandleOwnership transfer)
        : base(javaReference, transfer)
    { }

    public LoaderView(Context context)
        : base(context)
    { }

    public LoaderView(Context context, IAttributeSet attrs)
        : base(context, attrs)
    { }

    protected override void OnVisibilityChanged(View changedView, ViewStates visibility)
    {
        base.OnVisibilityChanged(changedView, visibility);

        if (visibility == ViewStates.Visible)
            StartAnimation(_animation);
        else
            ClearAnimation();
    }

    protected override void OnAttachedToWindow()
    {
        base.OnAttachedToWindow();
        Create();
    }

    private void Create()
    {
        if (Context == null)
            return;

        ImageService.Instance.LoadCompiledResource("loader_indicator")
            .Into(this);

        _animation = ApplyRotation();
    }

    private static RotateAnimation ApplyRotation() =>
        new RotateAnimation(
            0,
            360,
            Dimension.RelativeToSelf,
            0.5f,
            Dimension.RelativeToSelf,
            0.5f)
        {
            Duration = 1200,
            Interpolator = new DecelerateInterpolator(1.25f),
            RepeatCount = Animation.Infinite
        };

}

您可以嘗試將綁定表達式更改為:

set.Bind(loader).For(v => v.BindVisible()).To(vm => vm.IsLoading);

但是,您在實例化元素時應用 animation,而不是在設置可見性時應用。 因此 animation 可能正在運行,而元素不可見或反之亦然。 您可能希望在更合適的時間點啟動 animation。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM