Forum Xamarin.Android

How to indicate app is working

RonNYCRonNYC Member ✭✭✭
edited March 2019 in Xamarin.Android

Two of my procedures could be busy for a while, like 30+ seconds or longer, on occasion. Currently when I initiate one of them the app doesn't look any different. I've tried adding Toast messages ("Working....") but they do NOT display. The "Completed" message does display.

MakeToast("Working...");
var result = longRunningProcedure();
MakeToast("Completed!");

Is there a recommended way to indicate to the user they have initiated an action (as opposed to the app being dead)?

Tagged:

Answers

  • axaaxa Member ✭✭✭
    You probably simplified the example for brevity, but are you following typical asynchronous procedures.

    Something more like:

    MakeToast("Working...");
    var result = await longRunningProcedure();
    MakeToast("Completed!");
  • jezhjezh Member, Xamarin Team Xamurai
    edited March 2019

    Toast is a method to indicate app is working, maybe there is some wrong in your code.
    Could you please post a basic demo so that we can test with it?

    Besides, in Xamarin.Android , you can also try ProgressDialog, which allows you to display a dialog with a spinner .
    And there is a demo you can check:
    https://www.c-sharpcorner.com/article/creating-a-progressdialog-in-xamarin-android-app-using-visual-studio-2015/

    From this link , we will see

    This class was deprecated in API level 26.
    ProgressDialog is a modal dialog, which prevents the user from interacting with the app. Instead of using this class, you should use a progress indicator like ProgressBar, which can be embedded in your app's UI. Alternatively, you can use a notification to inform the user of the task's progress.

    So we can use ProgressBar instead.

    Otherwise, if you want to have a spinner on your layout : https://forums.xamarin.com/discussion/72880/how-can-i-display-a-spinning-wheel-loading-indicator-while-loading-a-webview

  • axaaxa Member ✭✭✭

    Seems I entierly missed the point of your question...

    Before realizing there was a ProgressBar object, Ive used AnimationDrawable constructed in my OnCreate override:

    _backgroud = GetDrawable(Resource.Drawable.BlackBack400x400);   // get usual back ground from resources
    ListView.Background = _backgroud;                           // load to view background
    ListView.Background.Alpha = byte.MaxValue;                  // make sure its opaqe
    _busyAnime = (AnimationDrawable)GetDrawable(Resource.Drawable.Busy);    // get animation from resources
    _busyTimer = new Timer(OnBusyTimerExpired, null, 500, Timeout.Infinite);        // initialize timer
    

    Kick off my work, and give the the busy animation a 500mS, grace period (no point animating if the work finishes quickly)

    if or when the _busyTimer expiers the animation is loaded to the background and run

    private void OnBusyTimerExpired(object state)
    {
        RunOnUiThread(() =>
                        {
                            ListView.Background = _busyAnime;
                            _busyAnime.Start();
                        });
    }
    

    When the work finishes you can indiscrimintly stop the timer and replace the usual background regardless even if _busyTImer never had expired:
    Inside of busy work done handler:

    _busyTimer.Change(Timeout.Infinite, Timeout.Infinite);
    _busyAnime.Stop();
    ListView.Background = _backgroud;
    

    As for the animation it is a resource xml referancing all your frames like so:

    <?xml version="1.0" encoding="utf-8" ?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:oneshot="false">
        <item android:drawable="@drawable/Spinner00" android:duration="200" />
        <item android:drawable="@drawable/Spinner01" android:duration="200" />
        <item android:drawable="@drawable/Spinner02" android:duration="200" />
        <item android:drawable="@drawable/Spinner03" android:duration="200" />
        <item android:drawable="@drawable/Spinner04" android:duration="200" />
        <item android:drawable="@drawable/Spinner05" android:duration="200" />
        <item android:drawable="@drawable/Spinner06" android:duration="200" />
        <item android:drawable="@drawable/Spinner07" android:duration="200" />
        <item android:drawable="@drawable/Spinner08" android:duration="200" />
        <item android:drawable="@drawable/Spinner09" android:duration="200" />
        <item android:drawable="@drawable/Spinner10" android:duration="200" />
        <item android:drawable="@drawable/Spinner11" android:duration="200" />
    </animation-list>
    

    I find this works well when you wnat to have your own rather than stock animation.

    The key to all tis is to make sure you are working asyncrounously and nothing gets blocked, but thats a topic in and of itself

  • RonNYCRonNYC Member ✭✭✭

    This is a lot to absorb. So, apologies if I don't get back immediately. This is all extremely helpful.

  • RonNYCRonNYC Member ✭✭✭

    This is my code:

        progress = new Android.App.ProgressDialog(this);
                progress.Indeterminate = true;
                progress.SetProgressStyle(Android.App.ProgressDialogStyle.Spinner);
                progress.SetMessage("Work in progress...");
                progress.SetCancelable(false);
                runningProgressBar = true;
                progress.Show();
    

    It is definitely entered into. This code is run when the text I am working with is over a certain length.
    **YET, the progress bar does not appear.
    **
    I can make it appear if there are no conditions. That is, if this code is executed by another click event, unreleated to a long-running process. So the code definitely works.

    I have put the code far from the process itself and before the process is invoked.

Sign In or Register to comment.