Skip to content

Instantly share code, notes, and snippets.

@LeoAndo
Last active October 3, 2023 00:21
Show Gist options
  • Save LeoAndo/833038c37d1a1432b3a53e9614311005 to your computer and use it in GitHub Desktop.
Save LeoAndo/833038c37d1a1432b3a53e9614311005 to your computer and use it in GitHub Desktop.
[Android] アニメーションのヘルパークラス
package com.xxx.xxx; // TODO change your package name.
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;
import androidx.annotation.NonNull;
import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;
import androidx.transition.TransitionManager;
import com.google.android.material.transition.MaterialFade;
public final class ViewAnimationHelper {
private ViewAnimationHelper() {
}
public static void setVisibility(
final boolean isVisible,
@NonNull final ViewGroup sceneRoot,
@NonNull final View targetView) {
setVisibility(isVisible, 300L, sceneRoot, targetView);
}
/**
* アニメーションを使ったViewの表示/非表示.
*
* @param isVisible 表示フラグ. true: 表示 false: 非表示
* @param duration アニメーションの長さ(ミリ秒指定)
* @param sceneRoot トランジションを実行するビュー階層のルート
* @param targetView アニメーション対象View.
*/
public static void setVisibility(
final boolean isVisible,
final long duration,
@NonNull final ViewGroup sceneRoot,
@NonNull final View targetView) {
final MaterialFade fade = new MaterialFade();
fade.setDuration(duration);
TransitionManager.beginDelayedTransition(sceneRoot, fade);
final int visibility = (isVisible) ? View.VISIBLE : View.INVISIBLE;
targetView.setVisibility(visibility);
}
public static void startRotateAnimation(@NonNull final View targetView) {
startAnimation(
false,
targetView,
new BounceInterpolator(),
PropertyValuesHolder.ofFloat(View.ROTATION, 0.0f, 360.0f)
);
}
public static void startRotateAndScaleAnimation(@NonNull final View targetView) {
startAnimation(
false,
targetView,
new BounceInterpolator(),
PropertyValuesHolder.ofFloat(View.ROTATION, 0.0f, 360.0f), // 360度回転
PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.0f, 2.0f, 1.0f) // 2倍にスケールアップし元の倍率に戻る
);
}
/**
* アニメーション処理を行う
*
* @param isRepeatMode true: アニメーションをリピートさせる false: リピートさせない
* @param targetView アニメーションを適用するターゲットView
* @param timeInterpolator アニメーションパターン
* {@link AccelerateDecelerateInterpolator}, {@link AccelerateInterpolator}
* {@link AnticipateInterpolator} {@link AnticipateOvershootInterpolator}
* {@link BounceInterpolator} {@link CycleInterpolator} {@link DecelerateInterpolator}
* {@link FastOutLinearInInterpolator} {@link FastOutSlowInInterpolator}
* {@link LinearInterpolator} {@link LinearOutSlowInInterpolator} {@link OvershootInterpolator}
* @param values アニメーションをかけたいプロパティ値の指定(複数指定可能)
*/
public static void startAnimation(
final boolean isRepeatMode,
@NonNull final View targetView,
@NonNull final TimeInterpolator timeInterpolator,
@NonNull final PropertyValuesHolder... values
) {
final ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(targetView, values);
objectAnimator.setDuration(2000); // アニメーション時間 milliseconds指定
if (isRepeatMode) {
objectAnimator.setRepeatCount(1);
objectAnimator.setRepeatMode(ObjectAnimator.REVERSE);
}
objectAnimator.setInterpolator(timeInterpolator); // アニメーションパターンの適用
objectAnimator.start();
}
}
@LeoAndo
Copy link
Author

LeoAndo commented Aug 4, 2023

Usage : setVisibility

MainActivity.java

    boolean isVisibleFlg;

    @Override
    protected void onResume() {
        super.onResume();
        isVisibleFlg = !isVisibleFlg; // toggle
        ViewAnimationHelper.setVisibility(
                isVisibleFlg,
                800L,
                findViewById(R.id.root_layout),
                findViewById(R.id.target_view)
        );
    }

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/root_layout"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/target_view"
        android:visibility="invisible"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

capture API 30 (OS 11)

HOMEボタンを押してアプリの表示非表示を行うとアニメーションが実行される。

device-2023-08-04-190434.webm

@LeoAndo
Copy link
Author

LeoAndo commented Oct 3, 2023

Usage : startRotateAnimation / startRotateAndScaleAnimation

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final View targetView = findViewById(R.id.textView);
        // ViewAnimationHelper.startRotateAnimation(targetView);
        ViewAnimationHelper.startRotateAndScaleAnimation(targetView);
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

capture API 30 (OS 11)

アプリ起動時にアニメーション処理を行っています

startRotateAndScaleAnimation

device-2023-10-03-091416.webm

startRotateAnimation

device-2023-10-03-091353.webm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment