モーフィング効果を実現しようとしています。ユーザーが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();
}
これにより、矢印がチェックマークに変わります。プロセスを逆にするにはどうすればよいですか?
ビューがcheckable
であり、minsdk > 21
StateListAnimator
をAnimatedVectorDrawable
と一緒に使用してみることができますが、appcompat
はvectorDrawable
とAnimatedVectorDrawable
をサポートし、使用にも制限があるためです。すべてDrawableContainers
私は上記のアプローチを取りません。
それで、何がうまくいくかをお話ししましょう:
ベクターリソースのみを含む他のドローアブルリソースを参照するDrawableContainers。たとえば、ベクターを含む他のファイルを参照するStateListDrawable。
から Chris Banes
これを実現するには、カスタムImageView
を作成し、クリックするたびにmorph
関数を呼び出して適切なvectorAnimatorDrawable
を実行する必要があります。
したがって、コードとデモ:
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>
Circular Progress Buttonを使用します。必要に応じてカスタマイズしたり、ライブラリを拡張したりできます(オープンソースであるため)。私はそれをしばらく使用していて、プロジェクトに統合するのは非常に簡単です。
また、そこから学び、独自のライブラリを作成することもできます:-)
ここでGitリポジトリ CircularProgressButton
また、 Android Morphing Button などの他の優れたオープンソースを試すこともできます。