2016-02-27 13 views
8

Tôi đang cố gắng đạt được hiệu ứng biến đổi, khi người dùng nhấp vào myButton, hình ảnh bên trong ImageView sẽ biến đổi từ mũi tên thành dấu kiểm. Và khi anh ta nhấp vào nó một lần nữa, quá trình nên đảo ngược: dấu kiểm nên morph để mũi tên.Đảo ngược hoạt ảnh biến hình từ mũi tên để đánh dấu

Đây là những gì tôi đã làm:

animated_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" /> 

Và đây là cách tôi chơi hoạt hình:

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

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

Điều này biến hình mũi tên thành dấu kiểm, làm cách nào để đảo ngược quá trình?

Trả lời

16

nếu tầm nhìn của bạn là checkable và cũng bạn minsdk > 21 bạn có thể thử sử dụng StateListAnimator với AnimatedVectorDrawable nhưng vì appcompat bây giờ hỗ trợ vectorDrawableAnimatedVectorDrawable và cũng có một giới hạn về việc sử dụng tất cả DrawableContainers Tôi không mất trên cách tiếp cận.

Vì vậy, hãy để tôi nói cho bạn biết những gì có thể làm việc:

DrawableContainers mà tham khảo các nguồn lực drawables khác mà chỉ chứa một nguồn lực vector. Ví dụ: một StateListDrawable có các tham chiếu các tệp khác chứa một vectơ.

từ Chris Banes

Để đạt được điều đó tôi sẽ tạo tùy chỉnh ImageView và mỗi lần nó được nhấp, bạn phải gọi morph hàm để chạy thích hợp vectorAnimatorDrawable.

Vì vậy, mã và demo:

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

trong file layout bạn phải sử dụng nó như:

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

và các nguồn lực cho những ai muốn để cho nó một thử:

res/phim hoạt hình/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/phim hoạt hình/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> 
+1

Cảm ơn lời giải thích này - Trong những lần thực hiện chính xác điều này. Có vẻ như rất nhiều nỗ lực, tức là mã/tệp cho hoạt ảnh cơ bản hoàn toàn! –

+0

@MarkKeen Chỉ muốn làm điều này và câu trả lời chia nhỏ mã lên trong nhiều tệp cho cấu trúc, imho một chút quá mức, mã sẽ trở nên nhỏ hơn một chút nếu bạn không chia nhỏ xml hoạt ảnh. Điều chú thích bằng cách tách là bạn vẫn phải sao chép pathdata trong drawable và animation – Adam

7

Tôi sẽ đi với nút Progress Progress, bạn có thể tùy chỉnh nó dựa trên nhu cầu của bạn hoặc mở rộng thư viện (kể từ đó. đó là mã nguồn mở). Tôi đã sử dụng nó một thời gian và nó khá dễ dàng để tích hợp vào các dự án của bạn.

Ngoài ra, bạn có thể học hỏi từ đó và tạo thư viện riêng của bạn :-)

Đây kho Git CircularProgressButton

enter image description here

Ngoài ra, bạn có thể thử mã nguồn mở tuyệt vời khác như Android Morphing Button

enter image description here enter image description here

Các vấn đề liên quan