Как сделать анимацию бегущего прогрессбара?
У меня есть progressbar на который я хочу повесить анимацию бесконечно бегущей полоски.
Но я не понимаю, как это реализовать.
В моем main_activity.xml у меня есть progressbar и imageview(которое я буду анимировать)
<ProgressBar
android:id="@+id/progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
android:background="@color/colorWhite"
android:progress="0"
android:progressDrawable="@drawable/custom_progress_bar"
app:layout_constraintBottom_toTopOf="@+id/price"
app:layout_constraintEnd_toEndOf="@+id/progress_bar"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="parent" />
<ImageView
android:id="@+id/animated_image_on_progressbar"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="10dp"
app:srcCompat="@drawable/animated_veсtor_progressbar"
app:layout_constraintBottom_toTopOf="@+id/price"
app:layout_constraintEnd_toEndOf="@+id/progress_bar"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="parent" />
Также имеется файл progress_bar_animated.xml
<vector android:alpha="0.94" android:height="20dp"
android:viewportHeight="1500" android:viewportWidth="10500"
android:width="140dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:name="path_1" android:fillColor="#C5C6C6" android:pathData="M322,172h9787v915h-9787z"/>
<path android:name="path_2" android:fillColor="#898989" android:pathData="M333,1087l684,-915l1378,0l-665,915z"/>
<path android:name="path_3" android:fillColor="#898989" android:pathData="M2853,1087l684,-915l1378,0l-664,915z"/>
<path android:name="path_4" android:fillColor="#898989" android:pathData="M5367,1087l684,-915l1379,0l-665,915z"/>
<path android:name="path_5" android:fillColor="#898989" android:pathData="M7893,1087l684,-915l1379,0l-665,915z"/>
animated_vector
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/progressbar_animated">
<target
android:name="path_1"
android:animation="@animator/animate_progressbar" />
<target
android:name="path_2"
android:animation="@animator/animate_progressbar" />
<target
android:name="path_3"
android:animation="@animator/animate_progressbar" />
<target
android:name="path_4"
android:animation="@animator/animate_progressbar" />
<target
android:name="path_5"
android:animation="@animator/animate_progressbar" />
Я не очень понимаю, каким должен быть аниматор?
А также, как быть с размером, т.к размер менять не так просто в svg файлах, а размер progressbar (20dp and match_parent).
Ответы (1 шт):
Решение на pure SVG. Я думаю, что наверное будет возможно его перевести в android формат.
Идея заключается в создании прямоугольников, которые наклоняются на нужный угол с помощью команды transform="skewX(-45)"
Затем они клонируются <use xlink:href="#base" transform="translate(-150,0)"/> несколько раз до полного заполнения полоски.
Полоска анимируется с помощью команды
<animateTransform attributeName="transform" type="translate"
dur="2.5s" from="0 0" to="150 0" repeatCount="indefinite"/>
Начало анимации после клика по холсту SVG
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 100">
<rect x="0" y="0" width="600" height="40" fill="#3A8582" />
<!-- <rect x="20" y="10" width="560" height="80" fill="#d3d3d3" /> -->
<defs>
<g id="bshop" transform="skewX(-45)">
<g id="base">
<rect y="10" x="0" height="30%" width="40" fill="#DCDCDC"/>
<rect y="10" x="40" height="30%" width="35" fill="#7B7B7B"/>
<rect y="10" x="75" height="30%" width="40" fill="#DCDCDC"/>
<rect y="10" x="115" height="30%" width="35" fill="#7B7B7B"/>
</g>
<use xlink:href="#base" transform="translate(-150,0)"/>
<use xlink:href="#base" transform="translate(150,0)"/>
<use xlink:href="#base" transform="translate(300,0)"/>
</g>
<pattern id="barber" patternUnits="userSpaceOnUse" width="150" height="30" >
<use xlink:href="#bshop" transform="translate(0,0)">
<animateTransform attributeName="transform" type="translate" begin="svg1.click" dur="2.5s" from="0 0" to="150 0" repeatCount="indefinite"/>
</use>
</pattern>
</defs>
<rect x="10" y="10" height="30" width="580" rx="5" fill="url(#barber)"/>
</svg>
Вариант с объемной бегущей полосой
Для придания объема используется линейный градиент:
<linearGradient id="gradient1" x1="0" x2="0" y2="0.9">
<stop offset="0" stop-color="black"/>
<stop offset="0.3" stop-color="white" stop-opacity="0"/>
<stop offset="0.4" stop-color="white" stop-opacity=".8"/>
<stop offset="0.5" stop-color="white" stop-opacity=".6"/>
<stop offset="1" stop-color="black" stop-opacity=".9"/>
</linearGradient>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 100">
<rect x="0" y="0" width="600" height="50" fill="#3A8582" />
<!-- <rect x="20" y="10" width="560" height="80" fill="#d3d3d3" /> -->
<defs>
<g id="bshop" transform="skewX(-45)">
<g id="base">
<rect y="10" x="0" height="30%" width="40" fill="#DCDCDC"/>
<rect y="10" x="40" height="30%" width="35" fill="#7B7B7B"/>
<rect y="10" x="75" height="30%" width="40" fill="#DCDCDC"/>
<rect y="10" x="115" height="30%" width="35" fill="#7B7B7B"/>
</g>
<use xlink:href="#base" transform="translate(-150,0)"/>
<use xlink:href="#base" transform="translate(150,0)"/>
<use xlink:href="#base" transform="translate(300,0)"/>
</g>
<pattern id="barber" patternUnits="userSpaceOnUse" width="150" height="30" >
<use xlink:href="#bshop" transform="translate(0,0)">
<animateTransform attributeName="transform" type="translate" dur="2.5s" from="0 0" to="150 0" repeatCount="indefinite"/>
</use>
</pattern>
</defs>
<rect x="10" y="10" height="30" width="580" rx="5" fill="url(#barber)"/>
<linearGradient id="gradient1" x1="0" x2="0" y2="0.9">
<stop offset="0" stop-color="black"/>
<stop offset="0.3" stop-color="white" stop-opacity="0"/>
<stop offset="0.4" stop-color="white" stop-opacity=".8"/>
<stop offset="0.5" stop-color="white" stop-opacity=".6"/>
<stop offset="1" stop-color="black" stop-opacity=".9"/>
</linearGradient>
<rect x="10" y="10" width="580" height="30" rx="5" fill="url(#gradient1)"/>
</svg>
Вариант со счётчиком
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 100">
<rect x="0" y="0" width="600" height="50" fill="#3A8582" />
<!-- <rect x="20" y="10" width="560" height="80" fill="#d3d3d3" /> -->
<defs>
<g id="bshop" transform="skewX(-45)">
<g id="base">
<rect y="10" x="0" height="30%" width="40" fill="#DCDCDC"/>
<rect y="10" x="40" height="30%" width="35" fill="#7B7B7B"/>
<rect y="10" x="75" height="30%" width="40" fill="#DCDCDC"/>
<rect y="10" x="115" height="30%" width="35" fill="#7B7B7B"/>
</g>
<use xlink:href="#base" transform="translate(-150,0)"/>
<use xlink:href="#base" transform="translate(150,0)"/>
<use xlink:href="#base" transform="translate(300,0)"/>
</g>
<pattern id="barber" patternUnits="userSpaceOnUse" width="150" height="30" >
<use xlink:href="#bshop" transform="translate(0,0)">
<animateTransform attributeName="transform" type="translate" dur="2.5s" from="0 0" to="150 0" repeatCount="4"/>
</use>
</pattern>
</defs>
<rect x="10" y="10" height="30" width="580" rx="5" fill="url(#barber)"/>
<linearGradient id="gradient1" x1="0" x2="0" y2="0.9">
<stop offset="0" stop-color="black"/>
<stop offset="0.3" stop-color="white" stop-opacity="0"/>
<stop offset="0.4" stop-color="white" stop-opacity=".8"/>
<stop offset="0.5" stop-color="white" stop-opacity=".6"/>
<stop offset="1" stop-color="black" stop-opacity=".9"/>
</linearGradient>
<rect x="10" y="10" width="580" height="30" rx="5" fill="url(#gradient1)"/>
<!-- Проценты -->
<rect x="250" y="16" height="16" width="40" rx="5" fill="#DCDCDC" stroke="#7B7B7B" stroke-width="0.6" />
<text id="count" x="270" y="21" text-anchor="middle" dy="7" font-size="14" fill="#111111">100%</text>
</svg>
<script>
var count = $(('#count'));
$({ Counter: 0 }).animate({ Counter: count.text() }, {
duration: 10000,
easing: 'linear',
step: function () {
count.text(Math.ceil(this.Counter)+ "%");
}
});
</script>
Вариант с объемной цветной бегущей полосой
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 600 100">
<rect x="0" y="0" width="600" height="50" fill="#3A8582" />
<defs>
<g id="bshop" transform="skewX(-45)">
<g id="base">
<rect y="10" x="0" height="30%" width="40" fill="#e12"/>
<rect y="10" x="40" height="30%" width="35" fill="#ddd"/>
<rect y="10" x="75" height="30%" width="40" fill="#11c"/>
<rect y="10" x="115" height="30%" width="35" fill="#ddd"/>
</g>
<use xlink:href="#base" transform="translate(-150,0)"/>
<use xlink:href="#base" transform="translate(150,0)"/>
<use xlink:href="#base" transform="translate(300,0)"/>
</g>
<pattern id="barber" patternUnits="userSpaceOnUse" width="150" height="30" >
<use xlink:href="#bshop" transform="translate(0,0)">
<animateTransform attributeName="transform" type="translate" dur="2.5s" from="0 0" to="150 0" repeatCount="indefinite"/>
</use>
</pattern>
</defs>
<rect x="10" y="10" height="30" width="580" rx="5" fill="url(#barber)"/>
<linearGradient id="gradient1" x1="0" x2="0" y2="1">
<stop offset="0" stop-color="black"/>
<stop offset="0.3" stop-color="white" stop-opacity="0.2"/>
<stop offset="0.4" stop-color="white" stop-opacity=".9"/>
<stop offset="0.6" stop-color="white" stop-opacity="0.6"/>
<stop offset="1" stop-color="black" stop-opacity=".9"/>
</linearGradient>
<rect x="10" y="5" width="580" height="30" rx="5" fill="url(#gradient1)"/>
</svg>