Анимация круговой галочки Android

Я пытаюсь добиться чего-то похожего на BEMAnimationTypeStroke, который можно найти в библиотеке iOS BEMCheckBox.

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

drawable/vector_drawable_ic_check_circle_white_48px.xml

    <path
            android:name="check"
            android:fillColor="#FFFFFF"
            android:pathData="M37.1,13.6L18.4,32.3h1.7l-8.5-8.5L10,25.5l8.5,8.5l0.8,0.8l0.8-0.8l18.7-18.7L37.1,13.6L37.1,13.6z"/>
    <path
            android:name="circle"
            android:fillColor="#FFFFFF"
            android:pathData="M24,48c13.3,0,24-10.7,24-24S37.3,0,24,0S0,10.7,0,24S10.7,48,24,48L24,48z
M24,45.6
C12.1,45.6,2.4,35.9,2.4,24S12.1,2.4,24,2.4S45.6,12.1,45.6,24S35.9,45.6,24,45.6L24,45.6z"/>
</vector>

anim/transform.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
            android:duration="1000"
            android:propertyName="fillColor"
            android:valueFrom="@color/transparent"
            android:valueTo="@color/white"/>
</set>

drawable/animation.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/vector_drawable_ic_check_circle_white_48px">
    <target
            android:name="check"
            android:animation="@anim/change_color"/>
</animated-vector>

И когда макет установлен, я запускаю анимацию, используя:

ImageView mCpuImageView = (ImageView) findViewById(R.id.animated_check);
Drawable drawable = mCpuImageView.getDrawable();
if (drawable instanceof Animatable) {
    ((Animatable) drawable).start();
}

Кто-нибудь может мне с этим помочь? Есть ли более простой способ добиться этого (пользовательский вид или существующая библиотека)?

Идея состоит в том, что я хочу иметь галочку в круге, и я хочу анимировать путь галочки. Когда он отображается, будет виден только круг, а затем будет анимировано создание галочки. Если другие настройки, такие как анимация круга одновременно с анимацией галочки, легко реализовать, это было бы лучше, но сначала я хочу анимировать только галочку.

LE: В конце концов я решил создать анимацию вручную с помощью пользовательского представления. Если у кого-нибудь есть представление о том, как я могу добиться этого с помощью векторного рисования, это будет хорошей практикой разработки. Спасибо.


person Ionut Negru    schedule 22.08.2016    source источник


Ответы (5)


Я искал то же самое, этот пост почти все объясняет. Код из этого поста:

drawable/check_mark.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportHeight="24.0"
    android:viewportWidth="24.0">
    <group android:name="background">
        <path
            android:name="circle"
            android:fillColor="@color/colorPrimary"
            android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0" />
    </group>
    <group android:name="check">
        <path
            android:name="tick"
            android:pathData="M6,11 l0,0 l0,0"
            android:strokeColor="@color/colorAccent"
            android:strokeWidth="1" />
    </group>

</vector>

drawable-v21/animated_check.xml

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/check_mark">
    <target
        android:name="tick"
        android:animation="@anim/check_animation" />
</animated-vector>

anim/check_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:ordering="sequentially"
    android:shareInterpolator="false">
    <!-- Step 1 -->
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="pathData"
        android:valueFrom="M6,11 l0,0 l0,0"
        android:valueTo="M6,11 l3.5,4 l0,0"
        android:valueType="pathType" />
    <!-- Step 2 -->
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="pathData"
        android:valueFrom="M6,11 l3.5,4 l0,0"
        android:valueTo="M6,11 l3.5,4 l8,-7"
        android:valueType="pathType" />
</set>

Использование

XML макета

<ImageView
    android:id="@+id/imageView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:visibility="visible"
    app:srcCompat="@drawable/animated_check" />

Java-класс

mImgCheck = (ImageView) findViewById(R.id.imageView);
((Animatable) mImgCheck.getDrawable()).start();
person s-hunter    schedule 10.04.2017
comment
это не делает никакой анимации - person Fajar Khan; 04.07.2017
comment
Не знаю, почему это не сработало для вас, но это сработало для меня. - person s-hunter; 05.07.2017
comment
Это работает для noughat .. не работает в marshmellow. Можете ли вы предоставить решение - person Vinodh Kumar; 15.09.2017
comment
Да, это работает, но нужно сделать одно небольшое изменение: вам нужно использовать android:src вместо app:srcCompat. - person immodi; 05.02.2018
comment
попробуйте поменять цвет, если у кого-то не работает. - person kapsid; 26.08.2020

Вы можете сделать это с помощью библиотеки Lottie, которую создали ребята из Airbnb.

Он имеет большие наборы значков и анимацию, которые можно легко интегрировать с использованием языка разработки Android, т.е. Java и Kotlin.

А вот и ссылка на тиковую анимацию, которую вы искали.

Чтобы использовать этот значок, вам необходимо загрузить json файл этого значка, добавить его в свою папку assets и следовать инструкциям на странице документация.

person Himanshu Agarwal    schedule 19.11.2018
comment
Спасибо. Это действительно хороший вариант. Я больше не работаю над этой функцией (решил ее с помощью других решений), но, возможно, это может помочь другим. - person Ionut Negru; 25.02.2019

Анимация создания галочки может быть достигнута путем анимации атрибута trimPathEnd пути галочки (см. https://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html). Значение атрибута trimPathEnd означает процент пути, где должен быть конец, обрезая все, что выходит за этот процент. Анимация trimPathEnd от 0 до 1 покажет от 0% до 100% пути галочки.

В следующем определении AnimatedVectorDrawable мы ссылаемся на анимацию с именем trim_path:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/vector_drawable_ic_check_circle_white_48px">
    <target
            android:name="check"
            android:animation="@anim/trim_path"/>
</animated-vector>

Затем в anim/trim_path.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
            android:duration="1000"
            android:propertyName="trimPathEnd"
            android:valueFrom="0"
            android:valueTo="1"/>
</set>

Это должно создать AnimatedVectorDrawable с флажком, растущим от 0% до 100%. Точно так же вы можете анимировать trimPathEnd на круге. Обратите внимание, что вам может понадобиться продублировать путь круга, чтобы один круг был серым и статичным, а другой круг был синим и анимировался сверху.

person Doris Liu    schedule 22.11.2016
comment
mCpuImageView.getDrawable() дает мне чертеж, который является экземпляром VectorDrawable, а не Animatable - person kdas; 24.02.2017

Это решение написано в одном xml-файле:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    xmlns:tools="http://schemas.android.com/tools"
    tools:targetApi="lollipop">
    <aapt:attr name="android:drawable">
        <vector
            android:width="50dp"
            android:height="50dp"
            android:viewportWidth="24.0"
            android:viewportHeight="24.0">
            <group android:name="check">
                <path
                    android:name="done"
                    android:pathData="M6,11 l0,0 l0,0"
                    android:strokeWidth="1"
                    android:strokeColor="@color/black" />
            </group>

        </vector>
    </aapt:attr>
    <target android:name="done">
        <aapt:attr name="android:animation">
            <set
                android:interpolator="@android:anim/accelerate_interpolator"
                android:ordering="sequentially"
                android:shareInterpolator="false">
                <!-- Step 1 -->
                <objectAnimator
                    android:duration="@android:integer/config_shortAnimTime"
                    android:propertyName="pathData"
                    android:valueFrom="M6,11 l0,0 l0,0"
                    android:valueTo="M6,11 l3.5,4 l0,0"
                    android:valueType="pathType" />
                <!-- Step 2 -->
                <objectAnimator
                    android:duration="@android:integer/config_shortAnimTime"
                    android:propertyName="pathData"
                    android:valueFrom="M6,11 l3.5,4 l0,0"
                    android:valueTo="M6,11 l3.5,4 l8,-7"
                    android:valueType="pathType" />
            </set>
        </aapt:attr>
    </target>
person Androidz    schedule 08.06.2020

Меня устраивает. Просто следуйте приведенному выше XML-коду @s-hunter. в вашей деятельности изменить код. как показано ниже:

mImgCheck = (ImageView) findViewById(R.id.imageView);        
Drawable drawable = mImgCheck.getDrawable();
((Animatable) drawable).start();

Вы можете добавить rippleBackground для лучшего вида.

person Asesha George    schedule 28.06.2017
comment
это точно такой же код @s-hunter выше с вашим решением. - person Fajar Khan; 04.07.2017
comment
Я решил свою проблему, используя библиотеку. проверить мой ответ - person Fajar Khan; 04.07.2017