Thêm animation cho custom view Android (serie Canvas phần 3)

Custom animation view android

Chào mọi người, trong bài viết này mình sẽ tiếp tục hướng dẫn cho các bạn về tạo custom view trong android và cụ thể là tạo các animation.

Trước hết mình sẽ cho các bạn xem lại về vòng đời của một view mà mình đã giới thiệu ở bài đầu tiên.

Để một các hiệu ứng (animation) được diễn ra thì view đó phải được vẽ lại trong hàm onDraw(), có nghĩa là muốn thay đổi thì bạn phải có các giá trị mới như top, left, right… và gọi hàm invalidate() để vẽ lại layout.

Trong hàm init(), bạn gọi thêm cho mình hàm này, mục đích của nó là sau 2 giây thì giá trị left sẽ tăng từ 0 đến 100, và khi có thay đổi thì sẽ gọi hàm invalidate() giúp cho giao diện được vẽ lại với giá trị left mới, nên bạn sẽ thấy giao diện được dịch dần sang phải.

public void createAnimation() {
    ValueAnimator animator = ValueAnimator.ofInt(0, 100);
    animator.setDuration(2000);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            left = (int) animation.getAnimatedValue();
            invalidate();
        }
    });
}

Trong bài trước mình đang sử dụng con pacman, bây giờ mình muốn làm hiệu ứng cho nó đóng mở miệng liên tục, giống như đang ăn vậy. Do đó mình sẽ làm như sau:

public void createAnimation() {
        ValueAnimator animator = ValueAnimator.ofInt(0, 30);
        animator.setDuration(500);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                startAngle = (int) animation.getAnimatedValue();
                sweepAngle = 360 - startAngle*2;
                invalidate();
            }
        });
    }

 

Nhưng trong ví dụ trên bạn đang sử dụng 1 giá trị thay đổi, giả sử bạn cần 2 giá trị cùng một lúc thì ValueAnimator không thể đáp ứng được, do đó bạn cần dùng PropertyValuesHolder.

PropertyValuesHolder propertySweep = PropertyValuesHolder.ofInt(PROPERTY_SWEEP, 0, 30);
        PropertyValuesHolder propertyTransaction = PropertyValuesHolder.ofInt(PROPERTY_TRANSACTION, 0, 200);

        animator = new ValueAnimator();
        animator.setValues(propertySweep, propertyTransaction);
        animator.setDuration(2000);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                startAngle = (int) animation.getAnimatedValue(PROPERTY_SWEEP);
                sweepAngle = 360 - startAngle*2;
                left = (int) animation.getAnimatedValue(PROPERTY_TRANSACTION);
                invalidate();
            }
        });
        animator.start();

Trong cùng khoảng thời gian 2 giây thì có 2 giá trị cùng thay đổi, PROPERTY_SWEEP và PROPERTY_TRANSACTION chỉ là 2 giá trị mà mình tự định nghĩa để có thể lấy gia, bạn phải dùng hàm setValue()  để đưa các value animatior vào.

Khi bạn test thử thì hầu như các chuyển động đều là các chuyển động đều, tức là nó cứ từ từ mà không nhanh chậm theo kiểu có gia tốc. Để tạo ra các hiệu ứng chuyển động mà có gia tốc khác nhau như vậy thì bạn cần sử dụng hàm setInterpolator().

Ví dụ animator.setInterpolator(new AccelerateInterpolator());

AccelerateDecelerateInterpolator: tăng sau giảm tốc.

AccelerateInterpolator: tăng tốc.

DecelerateInterpolator: giảm tốc.

AnticipateInterpolator: lùi một chút kiểu lấy đà rồi lao lên.

OvershootInterpolator: chạy tràn ra ngoài rồi quay lại.

AnticipateOvershootInterpolator: kết hợp cả 2 cái trên, vừa lùi lại vừa tràn ra ngoài.

BounceInterpolator: hiệu ứng giống như quả bóng rơi xuống đất, nảy vài lần rồi mới dừng lại.

… và còn một số cái nữa, nhưng đa số là sử dụng những cái này.

Ngoài ra còn một số option nữa ví dụ như:

setReapeatMode(): thay đổi chế độ lặp, bạn muốn xem giá trị thì cứ Ctrl + Space trong android studio nhé.

setRepeatCount(): số lượng lần lặp.

 

Series Navigation<< Custom attributes view trong Android (Phần 2)

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *