Одновременная анимация множества частей вектора
Используя AnimatedVectorDrawables, можно применить определенные анимации к частям vectordrawable (см. Здесь). Например, рассмотрим vectordrawable, который называется vectordrawable.xml:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="64dp"
android:width="64dp"
android:viewportHeight="600"
android:viewportWidth="600" >
<path
android:name="path"
android:fillColor="#000000"
android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
</vector>
Который является vectordrawable, содержащий один путь (линию). Тогда желаемая анимация будет находиться в отдельном файле, который называется animator.xml, например:
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="4000"
android:propertyName="trimPathEnd"
android:valueFrom="0"
android:valueTo="1" />
</set>
Это будет анимация, показывающая нарисованную линию. Эти два xml-файла будут затем передаваться в третий анимированный vectordrawable xml-файл:
<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/vectordrawable">
<target
android:animation="@anim/animator"
android:name="path" />
</animated-vector>
Итак, вопрос в том, что, если ваш vectordrawable путь содержал большое количество путей, которые вы хотели оживить одновременно? Вы могли бы проделать это долгий путь, и вам нужно было бы дать каждому пути свое имя, а затем нацелить каждый путь с помощью одного и того же аниматора в вашем анимированном файле. Но если у вас есть более 20 путей, это займет много времени и будет грязным решением.
У вас есть возможность заключить набор путей в группу, а затем настроить таргетинг на одну группу. Но анимации для групп отличаются от анимации путей, то есть анимация trimPathEnd для группы невозможна, поэтому вы не можете применить эту анимацию к группе путей.
2 ответа
Я хочу предложить RichPath, чтобы сделать это, но я не рекомендую звонить RichPathAnimator.animate()
в длинном цикле вы можете добиться того же результата лучше, проверьте 3-й шаг в этом полном примере:
1- Нормальный vector_drawable.xml
с 6 дорожками:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="256dp"
android:viewportHeight="36.0"
android:viewportWidth="36.0"
android:width="256dp">
<path
android:pathData="M19.5,6.2l1.3-1.3c0.2-0.2,0.2-0.5,0-0.7c-0.2-0.2-0.5-0.2-0.7,0l-1.5,1.5C17.9,5.2,16.9,5,16,5c-1,0-1.9,0.2-2.7,0.6l-1.5-1.5c-0.2-0.2-0.5-0.2-0.7,0c-0.2,0.2-0.2,0.5,0,0.7l1.3,1.3C11,7.3,10,9,10,11h12C22,9,21,7.2,19.5,6.2z"
android:strokeColor="#A4c639"
android:strokeWidth="0.5"
android:trimPathEnd="1"/>
<path
android:pathData="M13.9,8.9H13V8h0.9V8.9z"
android:strokeColor="#A4c639"
android:strokeWidth="0.5"
android:trimPathEnd="1"/>
<path
android:pathData="M19,8.9h-0.9V8H19V8.9z"
android:strokeColor="#A4c639"
android:strokeWidth="0.5"
android:trimPathEnd="1"/>
<path
android:pathData="M10,22c0,0.5,0.4,1,1,1h1v3.5c0,0.8,0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5V23h2v3.5c0,0.8,0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5V23h1c0.5,0,1-0.5,1-1V12H10V22z"
android:strokeColor="#A4c639"
android:strokeWidth="0.5"
android:trimPathEnd="1"/>
<path
android:pathData="M24.5,12c-0.8,0-1.5,0.7-1.5,1.5v7c0,0.8,0.7,1.5,1.5,1.5s1.5-0.7,1.5-1.5v-7C26,12.7,25.3,12,24.5,12z"
android:strokeColor="#A4c639"
android:strokeWidth="0.5"
android:trimPathEnd="1"/>
<path
android:pathData="M7.5,12C6.7,12,6,12.7,6,13.5v7C6,21.3,6.7,22,7.5,22S9,21.3,9,20.5v-7C9,12.7,8.3,12,7.5,12z"
android:strokeColor="#A4c639"
android:strokeWidth="0.5"
android:trimPathEnd="1"/>
</vector>
2- Использование RichPathView
в вашем layout
часть ImageView
:
<com.richpath.RichPathView
android:id="@+id/richPathView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:vector="@drawable/vector_drawable" />
3- оживить все ваши пути одновременно.
RichPathView pathView = findViewById(R.id.richPathView);
RichPath[] paths = new RichPath[6];
for (int i = 0; i < paths.length; i++) {
paths[i] = pathView.findRichPathByIndex(i);
}
RichPathAnimator
.animate(paths)
.trimPathEnd(0, 1)
.duration(1600)
.start();
Кроме того, будет чище, если у нас есть API, как pathView.findAllRichPaths()
Я открыл вопрос для этого здесь
Я нашел библиотеку ( здесь), которая представляет новое представление в виде изображения, которое принимает векторные рисунки. Затем вы можете извлечь пути (или любую часть рисованного вектора) либо по имени, либо, что более важно, по индексу. Таким образом, это позволяет анимировать любое количество путей, создавая цикл for, например:
RichPathView view = findViewbyId(R.id.richpathview);
for(int i=0, i<100, i++){
RichPath richPath = view.findRichPathByIndex(i);
RichPathAnimator.animate(richPath)
.trimPathEnd(0, 1)
.duration(1000)
.start();
}
Этот блок будет "рисовать" первые 100 путей вектора, который можно нарисовать одновременно.
Таким образом, это позволяет вам анимировать части вектора, которые можно нарисовать, без необходимости явно называть и ссылаться на каждую отдельную часть.