implement a spinning activity indicator similar to iOS in Android
Asked Answered
S

5

11

I am trying to implement the spinning activity similar to the the one I have placed below in Android. I believe I should use the ProgressDialog. My issue arises from how to actually manipulate the ProgressDialog to appear like the activity indicator.

Any thoughts are welcome. A link to an example would even be better.

Thanks. enter image description here

REEDIT:

myProgress.java

public class myProgress extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    ProgressDialog d = (ProgressDialog)findViewById(R.id.progres);

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progres"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
<ProgressBar  
    android:id="@+id/progressBar"
    android:indeterminate="true" 
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true" 
/>
</RelativeLayout>
Syrupy answered 29/8, 2011 at 10:15 Comment(0)
H
7

this is how i achieve it

here is the code

@Override   
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_LOADING:
        final Dialog dialog = new Dialog(this, android.R.style.Theme_Translucent);          
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.loading);
        dialog.setCancelable(true);
        dialog.setOnCancelListener(new OnCancelListener() {             
            @Override
            public void onCancel(DialogInterface dialog) {
                //onBackPressed();
            }
        });
    return dialog;  

    default:
        return null;
    }
};

here is the loading.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progres"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
<ProgressBar  
    android:indeterminate="true" 
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true" 
/> 
</RelativeLayout>

call the dialog with

showDialog(DIALOG_LOADING);

hide it using

dismissDialog(DIALOG_LOADING);

UPDATE

if you want and custom indicator you can do the following in the layout.xml.

  1. replace the ProgressBar with an ImageView
  2. set the background of the ImageView to a AnimationDrawable
  3. you can start the animation in onPrepareDialog
Humectant answered 29/8, 2011 at 10:19 Comment(7)
Sam, may I have some more clarification. I have added the ProgressBar in xml however I can not access it using findViewById. Can you advise please?Syrupy
can you clean you project and build it.Humectant
Sam, the build works fine, I just get error that I can not cast from view to processdialog...Syrupy
please check i am not using ProgressDialog it is just a Dialog.Humectant
i have updated my code again. you have to override the onCreateDialog in your activity to be save from memory leaks.Humectant
Hey Sam, thanks for the advise..The code works now, however, it displays the Android indicator..I needed to implement the iOS type indicator I pasted in my question..I apologize if I was not clear. Is there a way I can make it appear that way? ThanksSyrupy
Thanks Sam, this was great adviceSyrupy
B
8

I wrote my own custom LoadingIndicatorView.

It consists of two files:

  • LoadingIndicatorBarView
  • LoadingIndicatorView

Pros:

  • Programmatically created, no PNG antics meaning scalable and crisp :D
  • Customizable bar colors and corner radius (if you understand my code)

Cons:

  • Not as performant as the iOS version (I'm just a beginner Android developer coming from iOS background, what do you expect?) :P

Disclaimer:

  • Don't blame me if your project blows up, I'm putting this as free public domain code.

You'll notice my coding style and structure resemble my iOS programming codes a lot. I do everything programmatically, no XML if I can get away with it.

How to use this Loading Indicator

After you've copied and pasted all three class source codes into their Java file, you want to use the LoadingIndicatorView class, you shouldn't need to touch the other class, unless you want to customise the colour or rounded corner of each bar.

Create an instance of LoadingIndicatorView like this in your Activity:

import com.companyName.myApplication.views.LoadingIndicatorView;

public class MyActivity extends AppCompatActivity
{
    public mainLayout RelativeLayout;
    ...
    public LoadingIndicatorView loadingIndicator;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        initViews();
        initLayouts();
        addViews();
    }

    public void initViews()
    {
        mainLayout = new RelativeLayout(this);
        mainLayout.setBackgroundColor(Color.BLACK);

        ...

        // ---------------------------------------------------
        // 40 here is the radius of the circle
        // try and use multiples of 2, e.g. 40, 60, 80 etc
        // ---------------------------------------------------
        loadingIndicator = new LoadingIndicatorView(this, 40);

        // hide until ready to start animating
        loadingIndicator.setAlpha(0.0f);
    }

    public void initLayouts()
    {
        ...

        // Need API level 17 for this, set in your AndroidManifeset.xml
        mainLayout.setId(View.generateViewId());
        loadingIndicator.setId(View.generateViewId());

        RelativeLayout.LayoutParams loadingIndicatorLayoutParams = new RelativeLayout.LayoutParams(
                (int)(loadingIndicator.radius * 2.0f),
                (int)(loadingIndicator.radius * 2.0f)
        );

        loadingIndicatorLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);

        loadingIndicator.setLayoutParams(loadingIndicatorLayoutParams);
    }

    public void addViews()
    {
        ...

        mainLayout.addView(loadingIndicator);

        setContentView(mainLayout);
    }
}

Once you're ready to show it, e.g. in a button click listener, then you call:

loadingIndicator.startAnimating();

When you want to stop and hide the indicator, call:

loadingIndicator.stopAnimating();

You end up with something like this:

loading indicator screenshot

LoadingIndicatorView.java

package com.companyName.myApplication.views;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.PorterDuff;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by Zhang on 11/02/16.
 */
public class LoadingIndicatorView extends RelativeLayout
{
    private Context context;

    private int numberOfBars;

    public ArrayList<LoadingIndicatorBarView> arrBars;

    public float radius;

    private boolean isAnimating;
    private int currentFrame;

    private final Handler handler = new Handler();
    private Runnable playFrameRunnable;

    public LoadingIndicatorView(Context context, float radius)
    {
        super(context);

        this.context = context;
        this.radius = radius;
        this.numberOfBars = 12;

        initViews();
        initLayouts();
        addViews();
        spreadBars();
    }

    public void initViews()
    {
        arrBars = new ArrayList<LoadingIndicatorBarView>();

        for(int i = 0; i < numberOfBars; i++)
        {
            LoadingIndicatorBarView bar = new LoadingIndicatorBarView(context, radius / 10.0f);

            arrBars.add(bar);
        }
    }

    public void initLayouts()
    {
        for(int i = 0; i < numberOfBars; i++)
        {
            LoadingIndicatorBarView bar = arrBars.get(i);

            bar.setId(View.generateViewId());

            RelativeLayout.LayoutParams barLayoutParams = new RelativeLayout.LayoutParams(
                    (int)(radius / 5.0f),
                    (int)(radius / 2.0f)
            );

            barLayoutParams.addRule(ALIGN_PARENT_TOP);
            barLayoutParams.addRule(CENTER_HORIZONTAL);

            bar.setLayoutParams(barLayoutParams);
        }
    }

    public void addViews()
    {
        for(int i = 0; i < numberOfBars; i++)
        {
            LoadingIndicatorBarView bar = arrBars.get(i);

            addView(bar);
        }
    }

    public void spreadBars()
    {
        int degrees = 0;

        for(int i = 0; i < arrBars.size(); i++)
        {
            LoadingIndicatorBarView bar = arrBars.get(i);

            rotateBar(bar, degrees);

            degrees += 30;
        }
    }

    private void rotateBar(LoadingIndicatorBarView bar, float degrees)
    {
        RotateAnimation animation = new RotateAnimation(0, degrees, radius / 10.0f, radius);
        animation.setDuration(0);
        animation.setFillAfter(true);

        bar.setAnimation(animation);
        animation.start();
    }

    public void startAnimating()
    {
        setAlpha(1.0f);

        isAnimating = true;

        playFrameRunnable = new Runnable()
        {
            @Override
            public void run()
            {
                playFrame();
            }
        };

        // recursive function until isAnimating is false
        playFrame();
    }

    public void stopAnimating()
    {
        isAnimating = false;

        setAlpha(0.0f);

        invalidate();

        playFrameRunnable = null;
    }

    private void playFrame()
    {
        if(isAnimating)
        {
            resetAllBarAlpha();
            updateFrame();

            handler.postDelayed(playFrameRunnable, 0);
        }
    }

    private void updateFrame()
    {
        if (isAnimating)
        {
            showFrame(currentFrame);
            currentFrame += 1;

            if (currentFrame > 11)
            {
                currentFrame = 0;
            }
        }
    }

    private void resetAllBarAlpha()
    {
        LoadingIndicatorBarView bar = null;

        for (int i = 0; i < arrBars.size(); i++)
        {
            bar = arrBars.get(i);

            bar.setAlpha(0.5f);
        }
    }

    private void showFrame(int frameNumber)
    {
        int[] indexes = getFrameIndexesForFrameNumber(frameNumber);

        gradientColorBarSets(indexes);
    }

    private int[] getFrameIndexesForFrameNumber(int frameNumber)
    {
        if(frameNumber == 0)
        {
            return indexesFromNumbers(0, 11, 10, 9);
        }
        else if(frameNumber == 1)
        {
            return indexesFromNumbers(1, 0, 11, 10);
        }
        else if(frameNumber == 2)
        {
            return indexesFromNumbers(2, 1, 0, 11);
        }
        else if(frameNumber == 3)
        {
            return indexesFromNumbers(3, 2, 1, 0);
        }
        else if(frameNumber == 4)
        {
            return indexesFromNumbers(4, 3, 2, 1);
        }
        else if(frameNumber == 5)
        {
            return indexesFromNumbers(5, 4, 3, 2);
        }
        else if(frameNumber == 6)
        {
            return indexesFromNumbers(6, 5, 4, 3);
        }
        else if(frameNumber == 7)
        {
            return indexesFromNumbers(7, 6, 5, 4);
        }
        else if(frameNumber == 8)
        {
            return indexesFromNumbers(8, 7, 6, 5);
        }
        else if(frameNumber == 9)
        {
            return indexesFromNumbers(9, 8, 7, 6);
        }
        else if(frameNumber == 10)
        {
            return indexesFromNumbers(10, 9, 8, 7);
        }
        else
        {
            return indexesFromNumbers(11, 10, 9, 8);
        }
    }

    private int[] indexesFromNumbers(int i1, int i2, int i3, int i4)
    {
        int[] indexes = {i1, i2, i3, i4};
        return indexes;
    }

    private void gradientColorBarSets(int[] indexes)
    {
        float alpha = 1.0f;

        LoadingIndicatorBarView barView = null;

        for(int i = 0; i < indexes.length; i++)
        {
            int barIndex = indexes[i];

            barView = arrBars.get(barIndex);


            barView.setAlpha(alpha);
            alpha -= 0.125f;
        }

        invalidate();
    }
}

LoadingIndicatorBarView.java

package com.companyName.myApplication.views;

import android.content.Context;
import android.graphics.Color;
import android.widget.RelativeLayout;

import com.companyName.myApplication.helper_classes.ToolBox;

/**
 * Created by Zhang on 11/02/16.
 */
public class LoadingIndicatorBarView extends RelativeLayout
{
    private Context context;
    private float cornerRadius;

    public LoadingIndicatorBarView(Context context, float cornerRadius)
    {
        super(context);

        this.context = context;
        this.cornerRadius = cornerRadius;

        initViews();
    }

    public void initViews()
    {
        setBackground(ToolBox.roundedCornerRectWithColor(
                Color.argb(255, 255, 255, 255), cornerRadius));

        setAlpha(0.5f);
    }

    public void resetColor()
    {
        setBackground(ToolBox.roundedCornerRectWithColor(
                Color.argb(255, 255, 255, 255), cornerRadius));

        setAlpha(0.5f);
    }
}

Toolbox.java

package com.companyName.myApplication.helper_classes;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;

/**
 * Created by Zhang on 3/02/16.
 */
public class ToolBox
{
    private static ToolBox instance;
    public Context context;

    private ToolBox()
    {

    }

    public synchronized static ToolBox getInstance()
    {
        if(instance == null)
        {
            instance = new ToolBox();
        }

        return instance;
    }

    public static ShapeDrawable roundedCornerRectOutlineWithColor(int color, float cornerRadius,
                                                                  float strokeWidth)
    {
        float[] radii = new float[] {
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius
        };

        RoundRectShape roundedCornerShape = new RoundRectShape(radii, null, null);

        ShapeDrawable shape = new ShapeDrawable();
        shape.getPaint().setColor(color);
        shape.setShape(roundedCornerShape);
        shape.getPaint().setStrokeWidth(strokeWidth);
        shape.getPaint().setStyle(Paint.Style.STROKE);

        return shape;
    }

    public static ShapeDrawable roundedCornerRectWithColor(int color, float cornerRadius)
    {
        float[] radii = new float[] {
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius
        };

        RoundRectShape roundedCornerShape = new RoundRectShape(radii, null, null);

        ShapeDrawable shape = new ShapeDrawable();
        shape.getPaint().setColor(color);
        shape.setShape(roundedCornerShape);

        return shape;
    }

    public static ShapeDrawable roundedCornerRectWithColor(int color, float topLeftRadius, float
            topRightRadius, float bottomRightRadius, float bottomLeftRadius)
    {
        float[] radii = new float[] {
                topLeftRadius, topLeftRadius,
                topRightRadius, topRightRadius,
                bottomRightRadius, bottomRightRadius,
                bottomLeftRadius, bottomLeftRadius
        };

        RoundRectShape roundedCornerShape = new RoundRectShape(radii, null, null);

        ShapeDrawable shape = new ShapeDrawable();
        shape.getPaint().setColor(color);
        shape.setShape(roundedCornerShape);

        return shape;
    }

    public static int getScreenWidth()
    {
        return Resources.getSystem().getDisplayMetrics().widthPixels;
    }

    public static int getScreenHeight()
    {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }

    public static int getScreenOrientation(Context context)
    {
        return context.getResources().getConfiguration().orientation;
    }

    public static boolean isLandscapeOrientation(Context context)
    {
        return getScreenOrientation(context) == Configuration.ORIENTATION_LANDSCAPE;
    }

}

This Toolbox class is my convenience helper class to create rounded corner shapes etc in all my projects.

Hope that helps :D

Bruxelles answered 11/2, 2016 at 10:23 Comment(1)
Thank you @Zhang! However, in my case I had different requirements for animation, color, radius, wanted to start it automatically and modify from xml. If someone is interested, I posted it as a separate answerSporulate
H
7

this is how i achieve it

here is the code

@Override   
protected Dialog onCreateDialog(int id) {
    switch (id) {
    case DIALOG_LOADING:
        final Dialog dialog = new Dialog(this, android.R.style.Theme_Translucent);          
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dialog.setContentView(R.layout.loading);
        dialog.setCancelable(true);
        dialog.setOnCancelListener(new OnCancelListener() {             
            @Override
            public void onCancel(DialogInterface dialog) {
                //onBackPressed();
            }
        });
    return dialog;  

    default:
        return null;
    }
};

here is the loading.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/progres"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
>
<ProgressBar  
    android:indeterminate="true" 
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true" 
/> 
</RelativeLayout>

call the dialog with

showDialog(DIALOG_LOADING);

hide it using

dismissDialog(DIALOG_LOADING);

UPDATE

if you want and custom indicator you can do the following in the layout.xml.

  1. replace the ProgressBar with an ImageView
  2. set the background of the ImageView to a AnimationDrawable
  3. you can start the animation in onPrepareDialog
Humectant answered 29/8, 2011 at 10:19 Comment(7)
Sam, may I have some more clarification. I have added the ProgressBar in xml however I can not access it using findViewById. Can you advise please?Syrupy
can you clean you project and build it.Humectant
Sam, the build works fine, I just get error that I can not cast from view to processdialog...Syrupy
please check i am not using ProgressDialog it is just a Dialog.Humectant
i have updated my code again. you have to override the onCreateDialog in your activity to be save from memory leaks.Humectant
Hey Sam, thanks for the advise..The code works now, however, it displays the Android indicator..I needed to implement the iOS type indicator I pasted in my question..I apologize if I was not clear. Is there a way I can make it appear that way? ThanksSyrupy
Thanks Sam, this was great adviceSyrupy
E
2

You are looking for progressDialog i believe. This link can you set you start with it.

http://www.helloandroid.com/tutorials/using-threads-and-progressdialog

 pd = ProgressDialog.show(this, "Working..", "Calculating Pi", true,
                                false);
private Handler handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                        pd.dismiss();
                        tv.setText(pi_string);

                }
        };
Enswathe answered 29/8, 2011 at 11:51 Comment(2)
Andro, thanks for the link..However, I am very conversant with the way the progress works..my query is how to implement the one I pasted in my question..please refer to it.Syrupy
That's progress bar. But I am not sure about the style. I am sure a little search can get you there. am sorry I couldn't help you.Enswathe
S
2

Just look at this library. IOSDialog/Spinner library

It is very easy to use and solves your problem. With it, you can easily create and use spinner like in IOS. The example of code:

final IOSDialog dialog1 = new IOSDialog.Builder(IOSDialogActivity.this)
            .setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    dialog0.show();
                }
            })
            .setDimAmount(3)
            .setSpinnerColorRes(R.color.colorGreen)
            .setMessageColorRes(R.color.colorAccent)
            .setTitle(R.string.standard_title)
            .setTitleColorRes(R.color.colorPrimary)
            .setMessageContent("My message")
            .setCancelable(true)
            .setMessageContentGravity(Gravity.END)
            .build();

Result

 final IOSDialog dialog0 = new IOSDialog.Builder(IOSDialogActivity.this)
            .setTitle("Default IOS bar")
            .setTitleColorRes(R.color.gray)
            .build();

Result: stadard IOS Dialog

Spoilsman answered 17/6, 2017 at 9:43 Comment(2)
@BaummitAugen Thank you, but you should not immediately reduce the reputationSpoilsman
That's not my downvote. Don't just assume stuff about people's actions.Orlosky
S
0

Thank you @zhang for you solution! In my case, according to my project's requirements, I had different animation (without background constant opacity): see the first animation here

Also, I had different color, radius, wanted animation to start automatically and modify color, radius from the xml. To achieve that, I modified LoadingIndicatorView.java and LoadingIndicatorBarView.java and added style in attrs.xml, Toolbox.java is unmodified (see below).

Example of usage:

  <utils.ioslikespinner.LoadingIndicatorView
            android:layout_width="100dp"
            android:layout_height="100dp"
            app:color="?colorPrimary"
            app:radius="50dp"/>

If you have similar requirements, then this is my code:

LoadingIndicatorView.java

package utils.ioslikespinner;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;

import com.milence.R;

import java.util.ArrayList;

/**
 * Created by Zhang on 11/02/16 (https://mcmap.net/q/980942/-implement-a-spinning-activity-indicator-similar-to-ios-in-android)
 * Modified for design
 *
 * @noinspection ALL
 */
public class LoadingIndicatorView extends RelativeLayout {
    private final Handler handler = new Handler();
    public ArrayList<LoadingIndicatorBarView> arrBars;
    public float radius;
    private Context context;
    private int numberOfBars;

    private int color;
    private boolean isAnimating;
    private int currentFrame;
    private Runnable playFrameRunnable;

    public LoadingIndicatorView(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (attrs != null) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoadingIndicatorView);

            this.color = typedArray.getColor(R.styleable.LoadingIndicatorView_color, Color.WHITE);
            this.radius = typedArray.getDimension(R.styleable.LoadingIndicatorView_radius, 33);
        }

        this.context = context;
        this.numberOfBars = 12;

        initViews();
        initLayouts();
        addViews();
        spreadBars();

        startAnimating();
    }

    public void initViews() {
        arrBars = new ArrayList<LoadingIndicatorBarView>();

        for (int i = 0; i < numberOfBars; i++) {
            LoadingIndicatorBarView bar = new LoadingIndicatorBarView(context, 100, this.color);

            arrBars.add(bar);
        }
    }

    public void initLayouts() {
        for (int i = 0; i < numberOfBars; i++) {
            LoadingIndicatorBarView bar = arrBars.get(i);

            bar.setId(View.generateViewId());

            RelativeLayout.LayoutParams barLayoutParams = new RelativeLayout.LayoutParams(
                    (int) (radius / 5.0f),
                    (int) (radius / 2.0f)
            );

            barLayoutParams.addRule(ALIGN_PARENT_TOP);
            barLayoutParams.addRule(CENTER_HORIZONTAL);

            bar.setLayoutParams(barLayoutParams);
        }
    }

    public void addViews() {
        for (int i = 0; i < numberOfBars; i++) {
            LoadingIndicatorBarView bar = arrBars.get(i);

            addView(bar);
        }
    }

    public void spreadBars() {
        int degrees = 0;

        for (int i = 0; i < arrBars.size(); i++) {
            LoadingIndicatorBarView bar = arrBars.get(i);

            rotateBar(bar, degrees);

            degrees += 30;
        }
    }

    private void rotateBar(LoadingIndicatorBarView bar, float degrees) {
        RotateAnimation animation = new RotateAnimation(0, degrees, radius / 10.0f, radius);
        animation.setDuration(0);
        animation.setFillAfter(true);

        bar.setAnimation(animation);
        animation.start();
    }

    public void startAnimating() {
        setAlpha(1.0f);

        isAnimating = true;

        playFrameRunnable = new Runnable() {
            @Override
            public void run() {
                playFrame();
            }
        };

        // recursive function until isAnimating is false
        playFrame();
    }

    public void stopAnimating() {
        isAnimating = false;

        setAlpha(0.0f);

        invalidate();

        playFrameRunnable = null;
    }

    private void playFrame() {
        if (isAnimating) {
            resetAllBarAlpha();
            updateFrame();

            handler.postDelayed(playFrameRunnable, 100);
        }
    }

    private void updateFrame() {
        if (isAnimating) {
            showFrame(currentFrame);
            currentFrame += 1;

            if (currentFrame > 11) {
                currentFrame = 0;
            }
        }
    }

    private void resetAllBarAlpha() {
        LoadingIndicatorBarView bar = null;

        float alpha = 1f;


        for (int i = 0; i < arrBars.size(); i++) {
            bar = arrBars.get(i);

            bar.setAlpha(alpha);
        }
    }

    private void showFrame(int frameNumber) {
        int[] indexes = getFrameIndexesForFrameNumber(frameNumber);

        gradientColorBarSets(indexes);
    }

    private int[] getFrameIndexesForFrameNumber(int frameNumber) {
        if (frameNumber == 0) {
            return indexesFromNumbers(0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
        } else if (frameNumber == 1) {
            return indexesFromNumbers(1, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2);
        } else if (frameNumber == 2) {
            return indexesFromNumbers(2, 1, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3);
        } else if (frameNumber == 3) {
            return indexesFromNumbers(3, 2, 1, 0, 11, 10, 9, 8, 7, 6, 5, 4);
        } else if (frameNumber == 4) {
            return indexesFromNumbers(4, 3, 2, 1, 0, 11, 10, 9, 8, 7, 6, 5);
        } else if (frameNumber == 5) {
            return indexesFromNumbers(5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7, 6);
        } else if (frameNumber == 6) {
            return indexesFromNumbers(6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8, 7);
        } else if (frameNumber == 7) {
            return indexesFromNumbers(7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9, 8);
        } else if (frameNumber == 8) {
            return indexesFromNumbers(8, 7, 6, 5, 4, 3, 2, 1, 0, 11, 10, 9);
        } else if (frameNumber == 9) {
            return indexesFromNumbers(9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 11, 10);
        } else if (frameNumber == 10) {
            return indexesFromNumbers(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 11);
        } else {
            return indexesFromNumbers(11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
        }
    }

    private int[] indexesFromNumbers(int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9, int i10, int i11, int i12) {
        int[] indexes = {i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12};
        return indexes;
    }

    private void gradientColorBarSets(int[] indexes) {
        float alpha = 1.0f;

        LoadingIndicatorBarView barView = null;

        for (int i = 0; i < indexes.length; i++) {
            int barIndex = indexes[i];

            barView = arrBars.get(barIndex);


            barView.setAlpha(alpha);
            alpha -= 0.088f;
        }

        invalidate();
    }
}

LoadingIndicatorBarView.java

package utils.ioslikespinner;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.widget.RelativeLayout;


/**
 * Created by Zhang on 11/02/16 (https://mcmap.net/q/980942/-implement-a-spinning-activity-indicator-similar-to-ios-in-android)
 * Modified for design
 *
 * @noinspection ALL
 */
@SuppressLint("ALL")
public class LoadingIndicatorBarView extends RelativeLayout {
    private Context context;
    private float cornerRadius;
    private int color;

    public LoadingIndicatorBarView(Context context, float cornerRadius, int color) {
        super(context);

        this.context = context;
        this.cornerRadius = cornerRadius;
        this.color = color;

        initViews();
    }

    public void initViews() {
        setBackground(ToolBox.roundedCornerRectWithColor(color, cornerRadius));

        setAlpha(0.5f);
    }

    public void resetColor() {
        setBackground(ToolBox.roundedCornerRectWithColor(
                Color.argb(255, 255, 255, 255), cornerRadius));

        setAlpha(0.5f);
    }
}

Toolbox.java

package utils.ioslikespinner;

import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;

/**
 * Created by Zhang on 11/02/16 (https://mcmap.net/q/980942/-implement-a-spinning-activity-indicator-similar-to-ios-in-android)
 */
public class ToolBox {
    private static ToolBox instance;
    public Context context;

    private ToolBox() {

    }

    public synchronized static ToolBox getInstance() {
        if (instance == null) {
            instance = new ToolBox();
        }

        return instance;
    }

    public static ShapeDrawable roundedCornerRectOutlineWithColor(int color, float cornerRadius,
                                                                  float strokeWidth) {
        float[] radii = new float[]{
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius
        };

        RoundRectShape roundedCornerShape = new RoundRectShape(radii, null, null);

        ShapeDrawable shape = new ShapeDrawable();
        shape.getPaint().setColor(color);
        shape.setShape(roundedCornerShape);
        shape.getPaint().setStrokeWidth(strokeWidth);
        shape.getPaint().setStyle(Paint.Style.STROKE);

        return shape;
    }

    public static ShapeDrawable roundedCornerRectWithColor(int color, float cornerRadius) {
        float[] radii = new float[]{
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius,
                cornerRadius, cornerRadius
        };

        RoundRectShape roundedCornerShape = new RoundRectShape(radii, null, null);

        ShapeDrawable shape = new ShapeDrawable();
        shape.getPaint().setColor(color);
        shape.setShape(roundedCornerShape);

        return shape;
    }

    public static ShapeDrawable roundedCornerRectWithColor(int color, float topLeftRadius, float
            topRightRadius, float bottomRightRadius, float bottomLeftRadius) {
        float[] radii = new float[]{
                topLeftRadius, topLeftRadius,
                topRightRadius, topRightRadius,
                bottomRightRadius, bottomRightRadius,
                bottomLeftRadius, bottomLeftRadius
        };

        RoundRectShape roundedCornerShape = new RoundRectShape(radii, null, null);

        ShapeDrawable shape = new ShapeDrawable();
        shape.getPaint().setColor(color);
        shape.setShape(roundedCornerShape);

        return shape;
    }

    public static int getScreenWidth() {
        return Resources.getSystem().getDisplayMetrics().widthPixels;
    }

    public static int getScreenHeight() {
        return Resources.getSystem().getDisplayMetrics().heightPixels;
    }

    public static int getScreenOrientation(Context context) {
        return context.getResources().getConfiguration().orientation;
    }

    public static boolean isLandscapeOrientation(Context context) {
        return getScreenOrientation(context) == Configuration.ORIENTATION_LANDSCAPE;
    }

}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<!--  ....  -->
<resources>
    <declare-styleable name="LoadingIndicatorView">
        <attr name="color" format="color" />
        <attr name="radius" format="dimension" />
    </declare-styleable>
</resources>
Sporulate answered 25/9, 2023 at 9:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.