MDNick2000
MDNick2000

Reputation: 11

How to show custom ProgressBar in AsyncTask?

I have a custom ProgressBar:

drawable/circle.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape
            android:shape="ring"
            android:thicknessRatio="16"
            android:useLevel="false">
            <solid android:color="#DDD" />
        </shape>
    </item>
    <item>
        <rotate
            android:fromDegrees="270"
            android:toDegrees="270">
            <shape
                android:shape="ring"
                android:thicknessRatio="16"
                android:useLevel="true">
                <gradient
                    android:endColor="#00101f"
                    android:startColor="#0078ff"
                    android:type="sweep" />
            </shape>
        </rotate>
    </item>
</layer-list>

values/styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Widget.App.CustomProgressBar" parent="Widget.AppCompat.ProgressBar">
        <item name="android:indeterminateOnly">false</item>
        <item name="android:progressDrawable">@drawable/circle</item>
    </style>
</resources>

layout/custom_progress_bar.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ProgressBar
        android:id="@+id/customProgressBar"
        style="@style/Widget.App.CustomProgressBar"
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:progress="0"
        android:min="0"
        android:max="100"
        />

    <TextView
        android:id="@+id/textViewProgress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Large"
        app:layout_constraintBottom_toBottomOf="@+id/customProgressBar"
        app:layout_constraintEnd_toEndOf="@+id/customProgressBar"
        app:layout_constraintStart_toStartOf="@+id/customProgressBar"
        app:layout_constraintTop_toTopOf="@+id/customProgressBar"
        android:text="0 %"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

I want it to be displayed on top of activity while some data is loading in the background. I tried this:

ProgressBar progressBar;

public class LoadData extends AsyncTask
    {

        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
            progressBar = new ProgressBar(MyActivity.this, null, 0, R.layout.custom_progress_bar);
            //MyActivity uses ConstraintLayout
            ConstraintLayout cl = findViewById(R.id.constraintLayout);
            ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT
            );
            progressBar.setLayoutParams(lp);
            progressBar.setVisibility(View.VISIBLE);
            cl.addView(progressBar);
        }

        @Override
        protected Object doInBackground(Object[] objects)
        {
            //load some data here
        }

        @Override
        protected void onPostExecute(Object o)
        {
           progressBar.setVisibility(View.GONE);
        }
    }

However, it didn't work - background tasks are executing, but ProgressBar isn't displayed. How do I show my ProgressBar on top of activity with AsyncTask?

Upvotes: 0

Views: 132

Answers (1)

MDNick2000
MDNick2000

Reputation: 11

I found a way to do what I what:

public class LoadData extends AsyncTask
    {
        //Dialog in fullscreen
        Dialog dlg = new Dialog(MyActivity.this, android.R.style.Theme_Light_NoTitleBar_Fullscreen);
        //View with custom_progress_bar layout
        View customProgress = LayoutInflater.from(MyActivity.this).inflate(R.layout.custom_progress_bar, null, false);

        //Elements of custom ProgressBar layout
        ProgressBar progressBar = customProgress.findViewById(R.id.customProgressBar);
        TextView progressText = customProgress.findViewById(R.id.textViewProgress);

        @Override
        protected void onPreExecute()
        {
            super.onPreExecute();
            dlg.setContentView(customProgress);
            dlg.show();
        }

        @Override
        protected Object doInBackground(Object[] objects)
        {
            int i = 0;
            while (i <= 100)
            {
                try {
                    // Sleep for 100 milliseconds to show the progress slowly.
                    Thread.sleep(100);
                    //calls onProgressUpdate
                    publishProgress(i);
                    i += 1;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //load some data here
        }

        @Override
        protected void onProgressUpdate(Object[] values) {
            super.onProgressUpdate(values);
            //Updates values of layout elements
            progressBar.setProgress(Integer.parseInt(String.valueOf(values[0])));
            progressText.setText(values[0] + " %");
        }

        @Override
        protected void onPostExecute(Object o)
        {
            //Dismisses dialog
            dlg.dismiss();
        }
    }

Basically, I created a View, set it to have custom_progress_bar layout and inflated a Dialog with mentioned View. On execution I show Dialog and just update values of its layout elements.

Upvotes: 1

Related Questions