Search code examples
c#androidxamarinmvvmcross

Xamarin Android ProgressBar


I'm struggling to use the ProgressBar in the MVVMCross structure of Xamarin Android. Originally, I wanted to bind the visibility of the ProgressBar to a field in my ViewModel. That proved difficult, I tried several permutations and tried suggestions from here: How to set visibility for ProgressBar in android MvvmCross Xamarin

I do have other elements such as buttons I have been able to successfully bind else where in my project, so I'm not sure why that was such a big issue. After many tries I decided to try setting the Visibility pragmatically in the ViewModel. I've tried several methods but what I finally thought would for sure work doesn't.

Xaml:

<ProgressBar
    android:id="@+id/progressBarMap"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:visibility="gone"
    style="@android:style/Widget.ProgressBar.Large" />

I've tried with and without having a default visibility. I've tried the local:MvxBind with several normal methods of binding, and then using a custom converter or with the Visibility plugin.

In my Fragment I regretfully set a FragmentActivity property in my ViewModel just to see if I can get this to work in some form (OnCreateView):

ViewModel.FragActivity = this.Activity;
ViewModel.Progress = view.FindViewById<Android.Widget.ProgressBar>(Resource.Id.progressBarMap);

Notice I did also try setting the ProgressBar to a field called Progress, and use it in my ViewModel.

Here is where I'm manipulating the ProgressBar in my ViewModel:

private void AddOfflinePoints()
{
    try
    {
        FragActivity.RunOnUiThread(() => 
        {
            //I've also tried using the above Progress property. That wasn't null but did not update.
            ProgressBar barOfProgression = FragActivity.FindViewById<ProgressBar>(Resource.Id.progressBarMap);
            //barOfProgression is null :(
            barOfProgression.Visibility = ViewStates.Visible;
            barOfProgression.Enabled = true;
        });

        //Code to run while spinning the progress bar (It is inside Task.Run)
    }
    catch (Exception)
    {
        //Exception Handling code...
    }

    FragActivity.RunOnUiThread(() => Progress.Visibility = ViewStates.Gone);
}

What am I doing wrong? I've tried many permutations, anything on Google and consulted the limited Xamarin documentation. Any help or pointers is much appreciated.

Thank you.


Solution

  • Turns out the issue was the Linker removing the Visibility property. I got the idea from this post: Visibility binding fails

    I added the following code in LinkerPleaseInclude:

    public static void Include(ProgressBar progressBar)
    {
        progressBar.Click += (s, e) => progressBar.Visibility = progressBar.Visibility - 1;
    }
    

    If anyone is curious how I did it, below is the code:

    Xaml:

    <ProgressBar
        android:id="@+id/progressBarMap"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        local:MvxBind="Visibility Visibility(ShowProgress)"
        style="@android:style/Widget.ProgressBar.Large" />
    

    ViewModel:

    private bool _showProgress;
    public bool ShowProgress
    {
        get => _showProgress;
        set => SetProperty(ref _showProgress, value);
    }
    

    Where SetProperty is from MvxNotifyPropertyChanged class.