Creé un archivo anim.xml como el siguiente para agitar la vista de imagen como el ícono de IOS temblando en Android. Sin embargo, no me proporciona el mismo resultado. ¿Hay alguna idea mejor?
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fromDegrees="-2"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="2" />
android
android-animation
Winston
fuente
fuente
view.StartAnimation(AnimationUtils.LoadAnimation(Resource.Animation.wobble))
. Más detalles aquí y aquí .Buena animación de batido ;
res / anim / shake.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="150" android:fromXDelta="-10%" android:repeatCount="5" android:repeatMode="reverse" android:toXDelta="10%"/> </set>
Cómo usarlo
final Animation animShake = AnimationUtils.loadAnimation(this, R.anim.shake); btn_done = (Button) findViewById(R.id.btn_act_confirm_done); btn_done.startAnimation(animShake);
Cómo usarlo (versión más simple):
btn_done.startAnimation(AnimationUtils.loadAnimation(this,R.anim.shake));
fuente
android:duration="50"
se ve mucho menos agitadas en mi opinión y se ve mejor muichPuedes probar esto:
shake.xml
<translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="1000" android:interpolator="@anim/cycle_7" />
ciclo_7.xml
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />
fuente
cycle_7.xml
se puede sustituir porandroid:repeatCount="7"
atributo en<translate .../>
intenta usar este:
<set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:duration="70" android:fromDegrees="-5" android:pivotX="50%" android:pivotY="50%" android:repeatCount="5" android:repeatMode="reverse" android:interpolator="@android:anim/linear_interpolator" android:toDegrees="5" /> <translate android:fromXDelta="-10" android:toXDelta="10" android:repeatCount="5" android:repeatMode="reverse" android:interpolator="@android:anim/linear_interpolator" android:duration="70" /> </set>
fuente
Para hacer un efecto de agitación como este
Primero defina la animación de agitación dentro de la carpeta anim como shake.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <rotate android:duration="70" android:fromDegrees="-5" android:interpolator="@android:anim/linear_interpolator" android:pivotX="50%" android:pivotY="50%" android:repeatCount="5" android:repeatMode="reverse" android:toDegrees="5" /> <translate android:duration="70" android:fromXDelta="-10" android:interpolator="@android:anim/linear_interpolator" android:repeatCount="5" android:repeatMode="reverse" android:toXDelta="10" /> </set>
Entonces en código
if (TextUtils.isEmpty(phone.getText()) || phone.getText().length() < 10) { //shake animation phone.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.shake)); }
fuente
Creé un efecto de vibración en Android y lo publiqué en GitHub. Vea si funciona mejor.
https://github.com/teoinke/ShakeAnimation
Código relevante:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/overshoot_interpolator" android:fillAfter="true"> <translate android:startOffset="100" android:fromXDelta="0%p" android:toXDelta="10%p" android:duration="50" /> <translate android:startOffset="150" android:fromXDelta="0%p" android:toXDelta="-25%p" android:duration="110" /> <translate android:startOffset="260" android:fromXDelta="0%p" android:toXDelta="25%p" android:duration="120" /> <translate android:startOffset="380" android:fromXDelta="0%p" android:toXDelta="-20%p" android:duration="130" /> <translate android:startOffset="510" android:fromXDelta="0%p" android:toXDelta="10%p" android:duration="140" /> </set>
fuente
Este funciona bastante bien (aunque no perfectamente) como un clon de agitación de "PIN incorrecto" de iOS:
final float FREQ = 3f; final float DECAY = 2f; // interpolator that goes 1 -> -1 -> 1 -> -1 in a sine wave pattern. TimeInterpolator decayingSineWave = new TimeInterpolator() { @Override public float getInterpolation(float input) { double raw = Math.sin(FREQ * input * 2 * Math.PI); return (float)(raw * Math.exp(-input * DECAY)); } }; shakeField.animate() .xBy(-100) .setInterpolator(decayingSineWave) .setDuration(500) .start();
fuente
/** * * @param view view that will be animated * @param duration for how long in ms will it shake * @param offset start offset of the animation * @return returns the same view with animation properties */ public static View makeMeShake(View view, int duration, int offset) { Animation anim = new TranslateAnimation(-offset,offset,0,0); anim.setDuration(duration); anim.setRepeatMode(Animation.REVERSE); anim.setRepeatCount(5); view.startAnimation(anim); return view; }
utilizar:
TextView tv; makeMeShake(tv,20,5); // it will shake quite fast
fuente
Creé una muy buena aproximación del temblor de iOS (cuando mantienes presionado un ícono para eliminar la aplicación de la pantalla de inicio). Debe aplicar dentro de su código, mediante programación, ya que requiere la generación de números aleatorios:
int dur1 = 70 + (int)(Math.random() * 30); int dur2 = 70 + (int)(Math.random() * 30); // Create an animation instance Animation an = new RotateAnimation(-3, 3, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // Set the animation's parameters an.setDuration(dur1); // duration in ms an.setRepeatCount(-1); // -1 = infinite repeated an.setRepeatMode(Animation.REVERSE); an.setFillAfter(true); // keep rotation after animation // Create an animation instance Animation an2 = new TranslateAnimation(-TranslateAnimation.RELATIVE_TO_SELF,0.02f, TranslateAnimation.RELATIVE_TO_SELF,0.02f, -TranslateAnimation.RELATIVE_TO_SELF,0.02f, TranslateAnimation.RELATIVE_TO_SELF,0.02f); // Set the animation's parameters an2.setDuration(dur2); // duration in ms an2.setRepeatCount(-1); // -1 = infinite repeated an2.setRepeatMode(Animation.REVERSE); an2.setFillAfter(true); // keep rotation after animation AnimationSet s = new AnimationSet(false);//false means don't share interpolators s.addAnimation(an); s.addAnimation(an2); // Apply animation to image view itemView.setAnimation(s);
Este código fue diseñado para aplicarse dentro de la vista de cuadrícula de un adaptador (getView), pero puede aplicarlo a cualquier vista cambiando la última línea a:
yourViewName.setAnimations (s);
fuente
itemView
aún no se agregó a ViewGroup. Si ya se agregó, utilíceloitemView.startAnimation(s)
en su lugar.Para usuarios de Kotlin:
Primero cree un archivo de recursos de animación llamado shake.xml . Haga clic con el botón derecho en la carpeta res en Android Studio, luego haga clic en Nuevo> Archivo de recursos de Android> ingrese agitar para el nombre del archivo y seleccione Animación para el menú desplegable Tipo de recurso. Haga clic en Aceptar.
En
shake.xml
el interior pegue lo siguiente:<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:duration="200" android:fromXDelta="-5%" android:repeatCount="3" android:repeatMode="reverse" android:toXDelta="5%"/> </set>
¡Ahora solo llámalo en una vista!
Desde dentro de un fragmento:
myView.startAnimation(AnimationUtils.loadAnimation(view!!.context, R.anim.shake))
Desde dentro de una actividad:
myView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake))
(nota:
myView
es el ID que se le da a la vista que desea animar)Si desea ajustar la animación, simplemente modifique los valores en
shake.xml
.fuente
startAnimation
yanim
(dentroR.anim.shake
) hay referencias sin resolver, por favor, ¿pueden ayudarme? graciasLa animación de oscilación de IOS no es tan simple, intente cambiar el pivote xey aleatoriamente al rotar. Sin embargo, debe cambiar el valor programáticamente. Puede ser que también puedas usar la animación de traducción simultáneamente
fuente
Golpeándome la cabeza durante más de dos horas, supe cómo sacudir y mover una vista.
Desafortunadamente, la respuesta aceptada no funcionará aparte de onCreateView del fragmento.
Ejemplo si tiene el método onClick y dentro de él. Tienes una animación como la de abajo, no funcionará.
Por favor revise el código.
DoneStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { register(view); } });
El método de registro tiene algunas verificaciones como el siguiente código
private void register(View view) { String type = typedThings.getText.toString(); String km = Km_Now.getText().toString(); if (serviceType == null) { animationServiceList = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_wobble); silverServiceButton.setAnimation(animationServiceList); generalServiceButton.setAnimation(animationServiceList); platinumServiceButton.setAnimation(animationServiceList); animationServiceList.start(); } else if (km == null) { animationEditText = AnimationUtils.loadAnimation(getActivity(), R.anim.shake_wobble); Km_Now.setAnimation(animationEditText); animationEditText.start(); }
La llamada animationServiceList.start (); nunca será llamado,
SOLUCIÓN: Utilice PropertyAnimator como ObjectAnimator.
fuente
Otras respuestas también son correctas, pero esto es un poco más suave que ellas, ya que utiliza un interpolador que produce números suaves para el movimiento hacia adelante y hacia atrás.
public class WobblyView extends ImageView implements ValueAnimator.AnimatorUpdateListener { private final ValueAnimator va = ValueAnimator.ofInt(-10, 10); public WobblyView(Context context) { this(context, null); } public WobblyView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public WobblyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setAdjustViewBounds(true); setImageResource(R.drawable.ic_logo); va.setInterpolator(new AccelerateDecelerateInterpolator()); va.setRepeatMode(ValueAnimator.REVERSE); va.setRepeatCount(ValueAnimator.INFINITE); va.setDuration(1000); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); va.addUpdateListener(this); va.start(); } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); va.removeUpdateListener(this); } @Override public void onAnimationUpdate(ValueAnimator animation) { int heading = (int) animation.getAnimatedValue(); setRotation(heading); } }
fuente