реализовать индикатор активности вращения, аналогичный iOS в Android - PullRequest
9 голосов
/ 29 августа 2011

Я пытаюсь реализовать спиннинг, похожий на тот, который я поместил ниже в Android.Я считаю, что я должен использовать ProgressDialog.Моя проблема возникает из-за того, как на самом деле манипулировать ProgressDialog, чтобы он выглядел как индикатор активности.

Любые мысли приветствуются.Ссылка на пример была бы даже лучше.

Спасибо.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>

Ответы [ 4 ]

6 голосов
/ 29 августа 2011

вот как я этого добиваюсь

вот код

@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;
    }
};

вот это 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>

вызовдиалоговое окно с

showDialog(DIALOG_LOADING);

скрыть, используя

dismissDialog(DIALOG_LOADING);

ОБНОВЛЕНИЕ

, если вы хотите и пользовательский индикатор, вы можете сделать следующее в layout.xml .

  1. замените ProgressBar на ImageView
  2. , установите для background ImageView значение AnimationDrawable
  3. Вы можете запустить анимацию в onPrepareDialog
3 голосов
/ 11 февраля 2016

Я написал свой собственный LoadingIndicatorView.

Он состоит из двух файлов:

  • LoadingIndicatorBarView
  • LoadingIndicatorView

За

  • Программно создан, без PNG-шалостей, означающих масштабируемость и четкость
  • Настраиваемые цвета полос и радиус угла (если вы понимаете мой код)

Против

  • Не такой производительный, как версия для iOS (я только начинающий разработчик Android, работающий на iOS, чего вы ожидаете?): P

Ответственность

  • Не вините меня, если ваш проект рушится, я помещаю это как бесплатный код общественного достояния.

Вы заметите, что мой стиль и структура кодирования очень напоминают мои программные коды iOS. Я делаю все программно, без XML, если мне это сойдет с рук.

Как использовать этот индикатор загрузки

После того, как вы скопировали и вставили все исходные коды трех классов в их Java-файл, вы хотите использовать класс LoadingIndicatorView, вам не нужно трогать другой класс, если вы не хотите настраивать цвет или округление угол каждого бара.

Создайте экземпляр LoadingIndicatorView, как это в вашей деятельности:

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);
    }
}

Как только вы будете готовы показать это, например, при нажатии кнопки прослушиватель, затем вы звоните:

loadingIndicator.startAnimating();

Если вы хотите остановить и скрыть индикатор, наберите:

loadingIndicator.stopAnimating();

В итоге вы получите что-то вроде этого:

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;
    }

}

Этот класс Toolbox - мой вспомогательный класс для создания округлых угловых фигур и т. Д. Во всех моих проектах.

Надеюсь, это поможет: D

2 голосов
/ 29 августа 2011

Вы ищете прогрессДиалог, я верю. Эту ссылку вы можете установить, чтобы начать с нее.

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);

                }
        };
0 голосов
/ 17 июня 2017

Просто посмотрите на эту библиотеку. Библиотека IOSDialog / Spinner

Она очень проста в использовании и решает вашу проблему.С его помощью вы можете легко создавать и использовать спиннер, как в IOS.Пример кода:

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();

Результат

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

Результат: стандартный диалог IOS

...