Reversing the morphing animation from arrow to checkmark

前端 未结 2 1574
广开言路
广开言路 2021-01-31 06:11

I am trying to achieve the morphing effect, when the user clicks myButton, the image inside the ImageView should morph from arrow to checkmark. And when he clicks it again, the

相关标签:
2条回答
  • 2021-01-31 06:27

    if your view is checkable and also your minsdk > 21 you can try using StateListAnimator with AnimatedVectorDrawable but because the appcompat now supports vectorDrawable and AnimatedVectorDrawable and also has a limitation on using all DrawableContainers I do not take above approach.

    So let me tell you what may work:

    DrawableContainers which reference other drawables resources which contain only a vector resource. For example, a StateListDrawable which references other files which contain a vector.

    from Chris Banes

    In order to achieve that I am going to create custom ImageView and every time it is clicked you must call morph function to run appropriate vectorAnimatorDrawable.

    So code and demo:

    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;
        }
    
    }
    

    and 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();
                }
            });
        }
    }
    

    in layout file you must use it like:

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

    and resources for those who wants to give it a try:

    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>
    
    0 讨论(0)
  • 2021-01-31 06:39

    I will go with Circular Progress Button, you can customize it based on your need or extend the library (since. it's open source). I have been using that for a while and it is pretty easy to integrate on your projects.

    Also, you can learn from that and create your own library :-)

    Here the Git repository CircularProgressButton

    Also, you can try out other excellent open source such as Android Morphing Button

    0 讨论(0)
提交回复
热议问题