Вращающееся изображение. Анимационный список или анимированный поворот? (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" />
Я также попытался использовать повторяющуюся анимацию вращения (используя в папке ресурса анимации), но я действительно предпочитаю просмотр версии списка анимации.
Каков рекомендуемый способ решения этой проблемы?
Ответы
Ответ 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-кадра изображения.
Однако я не понял, как контролировать скорость анимации: (.