web-dev-qa-db-ja.com

モーフィングアニメーションを矢印からチェックマークに戻す

モーフィング効果を実現しようとしています。ユーザーがmyButtonをクリックすると、ImageView内の画像が矢印からチェックマークにモーフィングするはずです。そして、もう一度クリックすると、プロセスが逆になります。チェックマークが矢印に変わります。

これは私がしたことです:

animation_vector.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:drawable="@drawable/vector_upvote">

    <target
        Android:name="rotationGroup"
        Android:animation="@anim/rotate_a_to_b" />

    <target
        Android:name="upvote"
        Android:animation="@animator/animator_upvote_to_checkmark" />
</animated-vector>

animator_upvote_to_checkmark.xml:

<objectAnimator
    Android:duration="250"
    Android:propertyName="pathData"
    Android:valueFrom="@string/svg_upvote"
    Android:valueTo="@string/svg_checkmark"
    Android:valueType="pathType"
    Android:repeatMode="reverse" />

そして、これは私がアニメーションを再生する方法です:

            Drawable drawable = upVote.getDrawable();
            if (drawable instanceof Animatable) {

                ((Animatable) drawable).start();
            }

これにより、矢印がチェックマークに変わります。プロセスを逆にするにはどうすればよいですか?

15
SMahdiS

ビューがcheckableであり、minsdk > 21StateListAnimatorAnimatedVectorDrawableと一緒に使用してみることができますが、appcompatvectorDrawableAnimatedVectorDrawableをサポートし、使用にも制限があるためです。すべてDrawableContainers私は上記のアプローチを取りません。

それで、何がうまくいくかをお話ししましょう:

ベクターリソースのみを含む他のドローアブルリソースを参照するDrawableContainers。たとえば、ベクターを含む他のファイルを参照するStateListDrawable。

から Chris Banes

これを実現するには、カスタムImageViewを作成し、クリックするたびにmorph関数を呼び出して適切なvectorAnimatorDrawableを実行する必要があります。

したがって、コードとデモ:

enter image description here

public class ArrowToCheckMarkMorphingImageView extends ImageView {

    private AnimatedVectorDrawable mArrowToCheckMark;
    private AnimatedVectorDrawable mCheckMarkToArrow;
    private boolean mIsShowingCheckMark;
    public ArrowToCheckMarkMorphingImageView(Context context) {
        super(context);
        init();
    }

    public ArrowToCheckMarkMorphingImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public ArrowToCheckMarkMorphingImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public ArrowToCheckMarkMorphingImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    public void init(){
        mIsShowingCheckMark = false;
        mArrowToCheckMark =
                (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.arrow_to_checkmark);
        mCheckMarkToArrow =
                (AnimatedVectorDrawable)getContext().getDrawable(R.drawable.checkmark_to_arrow);
        setImageDrawable(mArrowToCheckMark);
    }

    public void morph(){
        final AnimatedVectorDrawable drawable
                = mIsShowingCheckMark ? mCheckMarkToArrow : mArrowToCheckMark;
        setImageDrawable(drawable);
        drawable.start();
        mIsShowingCheckMark = !mIsShowingCheckMark;
    }

}

およびMainActivity

public class MainActivity extends AppCompatActivity {

    ArrowToCheckMarkMorphingImageView mArrowToCheckMarkImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        mArrowToCheckMarkImageView = (ArrowToCheckMarkMorphingImageView)findViewById(R.id.imageView);
        mArrowToCheckMarkImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mArrowToCheckMarkImageView.morph();
            }
        });
    }
}

レイアウトファイルでは、次のように使用する必要があります。

  <yourpackage.ArrowToCheckMarkMorphingImageView
        Android:id="@+id/imageView"
        Android:layout_width="50dp"
        Android:layout_height="50dp"
        Android:layout_centerInParent="true"
        />

試してみたい人のためのリソース:

res/animator/arrow_to_checkmark

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <objectAnimator
        Android:duration="500"
        Android:propertyName="pathData"
        Android:valueFrom="M7.41,15.41 L12,10.83 l4.59,4.58 L18,14 18,14 l-6,-6 -6,6z"
        Android:valueTo  ="M9,16.17 L4.83,12 l-1.42,1.41 L9,19 21,7 l-1.41,-1.41 0,0z"
        Android:valueType="pathType" />
    <objectAnimator
        Android:duration="500"
        Android:propertyName="fillColor"
        Android:valueFrom="#FF0000FF"
        Android:valueTo="#FF00FF00" />
</set>

res/animator/checkmark_to_arrow

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <objectAnimator
        Android:duration="500"
        Android:propertyName="pathData"
        Android:valueFrom="M9,16.17 L4.83,12 l-1.42,1.41 L9,19 21,7 l-1.41,-1.41 0,0z"
        Android:valueTo  ="M7.41,15.41 L12,10.83 l4.59,4.58 L18,14 18,14 l-6,-6 -6,6z"
        Android:valueType="pathType" />
    <objectAnimator
        Android:duration="500"
        Android:propertyName="fillColor"
        Android:valueFrom="#FF00FF00"
        Android:valueTo="#FF0000FF" />
</set>

res/drawable/arrow_to_checkmark

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:drawable="@drawable/ic_arrow_up_24dp">
    <target
        Android:animation="@animator/arrow_to_checkmark"
        Android:name="arrow"/>
</animated-vector>

res/drawable/checkmark_to_arrow

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:drawable="@drawable/ic_checkmark_24dp">
    <target
        Android:animation="@animator/checkmark_to_arrow"
        Android:name="checkmark"/>
</animated-vector>

res/drawable/ic_arrow_up_24dp

<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:width="24dp"
        Android:height="24dp"
        Android:viewportWidth="24.0"
        Android:viewportHeight="24.0">
    <path
        Android:name="arrow"
        Android:fillColor="#FF0000FF"
        Android:pathData="M7.41,15.41 L12,10.83 l4.59,4.58 L18,14 18,14 l-6,-6 -6,6z"/>
</vector>

res/drawable/ic_checkmark_24dp

<vector xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:width="24dp"
        Android:height="24dp"
        Android:viewportWidth="24.0"
        Android:viewportHeight="24.0">
    <path
        Android:name="checkmark"
        Android:fillColor="#FF00FF00"
        Android:pathData="M9,16.17 L4.83,12 l-1.42,1.41 L9,19 21,7 l-1.41,-1.41 0,0z"/>
</vector>
21
user5703518

Circular Progress Buttonを使用します。必要に応じてカスタマイズしたり、ライブラリを拡張したりできます(オープンソースであるため)。私はそれをしばらく使用していて、プロジェクトに統合するのは非常に簡単です。

また、そこから学び、独自のライブラリを作成することもできます:-)

ここでGitリポジトリ CircularProgressButton

enter image description here

また、 Android Morphing Button などの他の優れたオープンソースを試すこともできます。

enter image description hereenter image description here

8
Carlos