Files
Application/app/src/main/java/com/example/boidelov3/BoideloAnimationUtils.java
T

416 lines
13 KiB
Java

package com.example.boidelov3;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import androidx.core.content.ContextCompat;
/**
* Classe utilitaire pour les animations et effets visuels
*/
public class BoideloAnimationUtils {
private static final Interpolator OVERSHOOT = new OvershootInterpolator();
/**
* Anime le changement de couleur de fond d'une vue
*
* @param view La vue à animer
* @param targetColor La couleur cible
* @param duration La durée de l'animation en ms
*/
public static void animateBackgroundColor(View view, int targetColor, int duration) {
if (view == null) return;
int currentColor = getBackgroundColor(view);
if (currentColor == targetColor) return;
ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), currentColor, targetColor);
anim.setDuration(duration);
anim.addUpdateListener(animation -> {
int color = (int) animation.getAnimatedValue();
view.setBackgroundColor(color);
});
anim.start();
}
/**
* Anime le changement de couleur de fond avec la durée par défaut (500ms)
*/
public static void animateBackgroundColor(View view, int targetColor) {
animateBackgroundColor(view, targetColor, 500);
}
/**
* Obtient la couleur de fond actuelle d'une vue
*/
private static int getBackgroundColor(View view) {
if (view.getBackground() instanceof ColorDrawable) {
return ((ColorDrawable) view.getBackground()).getColor();
}
return 0xFFFFFFFF; // Blanc par défaut
}
/**
* Déclenche une vibration haptique
*
* @param context Le contexte
* @param duration Durée de la vibration en ms
*/
public static void triggerHapticFeedback(Context context, int duration) {
if (context == null) return;
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VibrationEffect effect = VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE);
vibrator.vibrate(effect);
} else {
vibrator.vibrate(duration);
}
}
}
/**
* Déclenche une vibration haptique courte (100ms)
*/
public static void triggerHapticFeedback(Context context) {
triggerHapticFeedback(context, 100);
}
/**
* Déclenche une vibration haptique de succès
*/
public static void triggerSuccessHaptic(Context context) {
if (context == null) return;
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
long[] pattern = {0, 50, 50, 50};
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
vibrator.vibrate(effect);
}
}
/**
* Déclenche une vibration haptique d'erreur
*/
public static void triggerErrorHaptic(Context context) {
if (context == null) return;
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
if (vibrator != null && vibrator.hasVibrator() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
long[] pattern = {0, 100, 50, 100};
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
vibrator.vibrate(effect);
}
}
/**
* Anime l'apparition d'une vue avec un effet de fade-in
*
* @param view La vue à animer
* @param duration Durée de l'animation
*/
public static void fadeIn(View view, int duration) {
if (view == null) return;
view.setAlpha(0f);
view.setVisibility(View.VISIBLE);
view.animate()
.alpha(1f)
.setDuration(duration)
.start();
}
/**
* Anime la disparition d'une vue avec un effet de fade-out
*
* @param view La vue à animer
* @param duration Durée de l'animation
*/
public static void fadeOut(View view, int duration) {
if (view == null) return;
view.animate()
.alpha(0f)
.setDuration(duration)
.withEndAction(() -> view.setVisibility(View.GONE))
.start();
}
/**
* Anime une vue avec un effet de scale
*
* @param view La vue à animer
* @param scale Échelle cible (1.0 = normal, 0.5 = moitié)
* @param duration Durée de l'animation
*/
public static void scale(View view, float scale, int duration) {
if (view == null) return;
view.animate()
.scaleX(scale)
.scaleY(scale)
.setDuration(duration)
.setInterpolator(OVERSHOOT)
.start();
}
/**
* Anime une vue avec un effet de slide depuis le bas
*
* @param view La vue à animer
* @param duration Durée de l'animation
*/
public static void slideUp(View view, int duration) {
if (view == null) return;
view.setTranslationY(view.getHeight());
view.setVisibility(View.VISIBLE);
view.animate()
.translationY(0f)
.setDuration(duration)
.setInterpolator(new android.view.animation.DecelerateInterpolator())
.start();
}
/**
* Applique une animation de pression à un bouton
*
* @param view La vue (bouton) à animer
*/
public static void applyButtonPressAnimation(View view) {
if (view == null) return;
view.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case android.view.MotionEvent.ACTION_DOWN:
v.animate()
.scaleX(0.95f)
.scaleY(0.95f)
.setDuration(100)
.start();
return true;
case android.view.MotionEvent.ACTION_UP:
case android.view.MotionEvent.ACTION_CANCEL:
v.animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(100)
.start();
v.performClick();
return true;
}
return false;
});
}
/**
* Anime une vue avec un effet de pulsation
*
* @param view La vue à animer
* @param duration Durée d'un cycle de pulsation
*/
public static void pulse(View view, int duration) {
if (view == null) return;
view.animate()
.scaleX(1.05f)
.scaleY(1.05f)
.setDuration(duration / 2)
.withEndAction(() -> {
view.animate()
.scaleX(1f)
.scaleY(1f)
.setDuration(duration / 2)
.start();
})
.start();
}
/**
* Anime une vue avec un effet de shake (tremblement)
*
* @param view La vue à animer
*/
public static void shake(View view) {
if (view == null) return;
Animation shake = AnimationUtils.loadAnimation(view.getContext(), R.anim.button_press);
view.startAnimation(shake);
}
/**
* Obtient la couleur depuis une ressource de couleur
*/
public static int getColorFromResource(Context context, int colorResId) {
return ContextCompat.getColor(context, colorResId);
}
/**
* Anime une vue avec un effet de bounce (rebond)
*
* @param view La vue à animer
* @param duration Durée de l'animation
*/
public static void bounce(View view, int duration) {
if (view == null) return;
view.animate()
.scaleY(0.8f)
.scaleX(0.8f)
.setDuration(duration / 2)
.setInterpolator(new android.view.animation.DecelerateInterpolator())
.withEndAction(() -> {
view.animate()
.scaleY(1f)
.scaleX(1f)
.setDuration(duration / 2)
.setInterpolator(OVERSHOOT)
.start();
})
.start();
}
/**
* Anime une vue pour la supprimer (slide out + fade out)
*
* @param view La vue à animer
* @param duration Durée de l'animation
* @param endAction Action à exécuter après l'animation
*/
public static void slideOutToRemove(View view, int duration, Runnable endAction) {
if (view == null) return;
view.animate()
.translationX(-view.getWidth())
.alpha(0f)
.setDuration(duration)
.setInterpolator(new android.view.animation.AccelerateInterpolator())
.withEndAction(endAction)
.start();
}
/**
* Anime l'apparition d'une vue (slide in + fade in)
*
* @param view La vue à animer
* @param duration Durée de l'animation
*/
public static void slideIn(View view, int duration) {
if (view == null) return;
view.setTranslationX(view.getWidth());
view.setAlpha(0f);
view.setVisibility(View.VISIBLE);
view.animate()
.translationX(0f)
.alpha(1f)
.setDuration(duration)
.setInterpolator(new android.view.animation.DecelerateInterpolator())
.start();
}
/**
* Anime une vue avec un effet de rotation
*
* @param view La vue à animer
* @param degrees Angle de rotation en degrés
* @param duration Durée de l'animation
*/
public static void rotate(View view, float degrees, int duration) {
if (view == null) return;
view.animate()
.rotation(degrees)
.setDuration(duration)
.setInterpolator(new android.view.animation.DecelerateInterpolator())
.start();
}
/**
* Anime une vue avec un effet de wiggle (gauche-droite)
*
* @param view La vue à animer
*/
public static void wiggle(View view) {
if (view == null) return;
view.animate()
.rotation(5f)
.setDuration(50)
.withEndAction(() -> {
view.animate()
.rotation(-5f)
.setDuration(50)
.withEndAction(() -> {
view.animate()
.rotation(3f)
.setDuration(50)
.withEndAction(() -> {
view.animate()
.rotation(0f)
.setDuration(50)
.start();
})
.start();
})
.start();
})
.start();
}
/**
* Anime une vue avec un effet de pop-in (apparition avec scale)
*
* @param view La vue à animer
* @param duration Durée de l'animation
*/
public static void popIn(View view, int duration) {
if (view == null) return;
view.setScaleX(0f);
view.setScaleY(0f);
view.setAlpha(0f);
view.setVisibility(View.VISIBLE);
view.animate()
.scaleX(1f)
.scaleY(1f)
.alpha(1f)
.setDuration(duration)
.setInterpolator(OVERSHOOT)
.start();
}
/**
* Anime une vue avec un effet de pop-out (disparition avec scale)
*
* @param view La vue à animer
* @param duration Durée de l'animation
* @param endAction Action à exécuter après l'animation
*/
public static void popOut(View view, int duration, Runnable endAction) {
if (view == null) return;
view.animate()
.scaleX(0f)
.scaleY(0f)
.alpha(0f)
.setDuration(duration)
.setInterpolator(new android.view.animation.AccelerateInterpolator())
.withEndAction(endAction)
.start();
}
}