Подтвердить что ты не робот

Вращающееся изображение. Анимационный список или анимированный поворот? (Android)

Я хочу создать вращающееся изображение прогресса и задаться вопросом, как лучше всего двигаться дальше. Я могу заставить его работать с списком анимации, например, 12 изображений, изменяющихся каждые 100 мс. Это прекрасно работает, но довольно утомительно создавать 12 изображений или для каждого размера и разрешения:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/ic_loading_grey_on_black_01" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_02" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_03" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_04" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_05" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_06" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_07" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_08" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_09" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_10" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_11" android:duration="100" />
<item android:drawable="@drawable/ic_loading_grey_on_black_12" android:duration="100" />

Я полагаю, что более простым решением является использование одного изображения на разрешение, а скорее поворот его для каждого кадра. В ресурсах платформы (android-sdk-windows/platform...) я нашел что-то под названием animated-rotate в файле drawable/search_spinner.xml, но если я скопирую код, получите ошибку компилятора, жалуясь на андроид: framesCount и android: frameDuration (API API Google 2.2 в Eclipse):

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/spinner_black_20"
android:pivotX="50%"
android:pivotY="50%"
android:framesCount="12"
android:frameDuration="100" />

Я также попытался использовать повторяющуюся анимацию вращения (используя в папке ресурса анимации), но я действительно предпочитаю просмотр версии списка анимации.

Каков рекомендуемый способ решения этой проблемы?

4b9b3361

Ответ 1

Rotate drawable, предложенный Правееном, не даст вам контроля над количеством кадров. Предположим, вы хотите реализовать пользовательский загрузчик, состоящий из 8 разделов:

gif_icon

Используя подход animation-list, вам нужно создать 8 кадров, повернутых на 45*frameNumber градусов вручную. Кроме того, вы можете использовать 1-й кадр и установить для него анимацию вращения:

progress_icon

Файл res/anim/progress_anim.xml:

<?xml version="1.0" encoding="utf-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite" />

Файл MainActivity.java

Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim);
a.setDuration(1000);
imageView.startAnimation(a);

Это даст вам гладкую анимацию вместо 8-ступенчатой. Чтобы исправить это, нам нужно реализовать пользовательский интерполятор:

a.setInterpolator(new Interpolator() {
    private final int frameCount = 8;

    @Override
    public float getInterpolation(float input) {
        return (float)Math.floor(input*frameCount)/frameCount;
    }
});

Также вы можете создать собственный виджет:

Файл res/values/attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ProgressView">
        <attr name="frameCount" format="integer"/>
        <attr name="duration" format="integer" />
    </declare-styleable>
</resources>

Файл ProgressView.java:

public class ProgressView extends ImageView {

    public ProgressView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setAnimation(attrs);
    }

    public ProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setAnimation(attrs);
    }

    public ProgressView(Context context) {
        super(context);
    }

    private void setAnimation(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressView);
        int frameCount = a.getInt(R.styleable.ProgressView_frameCount, 12);  
        int duration = a.getInt(R.styleable.ProgressView_duration, 1000);
        a.recycle();

        setAnimation(frameCount, duration);
    }

    public void setAnimation(final int frameCount, final int duration) {
        Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim);
        a.setDuration(duration);
        a.setInterpolator(new Interpolator() {

            @Override
            public float getInterpolation(float input) {
                return (float)Math.floor(input*frameCount)/frameCount;
            }
        });
        startAnimation(a);
    }
}

Файл activity_main.xml:

<com.example.widget.ProgressView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_progress" 
    app:frameCount="8"
    app:duration="1000"/>

Файл res/anim/progress_anim.xml: перечисленные выше

Ответ 2

Вам нужно создать гибкий XML файл, как показано ниже:

код:

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0"
android:toDegrees="360" android:drawable="@drawable/imagefile_to_rotate" />

Ответ 3

Я нашел вокилам, чтобы ответить, чтобы быть лучшим, чтобы создать приятную ступенчатую/ступенчатую анимацию. Я пошел на свое последнее предложение и сделал собственный виджет, единственная проблема, с которой я столкнулся, заключалась в том, что настройка видимости не сработала, потому что она была анимирована и, следовательно, всегда была бы видна...

Я скорректировал его код (ProgressView.java, который я переименовал StaggeredProgress.java) следующим образом:

public class StaggeredProgress extends ImageView {

private Animation staggered;

public StaggeredProgress(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    setAnimation(attrs);
}

public StaggeredProgress(Context context, AttributeSet attrs) {
    super(context, attrs);
    setAnimation(attrs);
}

public StaggeredProgress(Context context) {
    super(context);
}

private void setAnimation(AttributeSet attrs) {
    TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StaggeredProgress);
    int frameCount = a.getInt(R.styleable.StaggeredProgress_frameCount, 12);  
    int duration = a.getInt(R.styleable.StaggeredProgress_duration, 1000);
    a.recycle();

    setAnimation(frameCount, duration);
}

public void setAnimation(final int frameCount, final int duration) {
    Animation a = AnimationUtils.loadAnimation(getContext(), R.anim.progress_anim);
    a.setDuration(duration);
    a.setInterpolator(new Interpolator() {

        @Override
        public float getInterpolation(float input) {
            return (float)Math.floor(input*frameCount)/frameCount;
        }
    });
    staggered = a;
    //startAnimation(a);
}

@Override
public void setVisibility(int visibility) {
    super.setVisibility(visibility);
    if( visibility == View.VISIBLE )
        startAnimation(staggered);
    else
        clearAnimation();

}


}

Этот способ настройки видимости видимости начинается и останавливает анимацию по мере необходимости... Большое спасибо снова вокилам!

Ответ 4

см. примеры здесь http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/index.html

а именно: Панель выполнения

  • Инкрементальный Демонстрирует большие и малые поворотные индикаторы прогресса, которые могут увеличиваться или уменьшаться в единицах.
  • Smooth Демонстрирует большие и малые непрерывно вращающиеся индикаторы прогресса, используемые для обозначения общего "занятого" сообщения.
  • Диалоги Демонстрирует диалоговое окно ProgressDialog, в котором отображается индикатор выполнения. Этот пример демонстрирует как определенные, так и неопределенные индикаторы прогресса.
  • В строке заголовка Демонстрирует экран активности с индикатором прогресса, загруженным установкой индикатора хода индикатора WindowPolicy.

Ответ 5

Решение SACPK определенно работает. Другим решением может быть использование <animated-rotate> точно так же, как в вопросе, и удалить атрибуты android:framesCount="12" android:frameDuration="100" для тех, которые компилятор жалуется. Он по-прежнему работает даже для моего 8-кадра изображения.

Однако я не понял, как контролировать скорость анимации: (.