Utworzyłem plik anim.xml, taki jak poniżej, aby potrząsać widokiem obrazu, takim jak ikona IOS w systemie Android. Jednak nie daje mi to takiego samego rezultatu. Czy jest lepszy pomysł?
<?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
źródło
źródło
view.StartAnimation(AnimationUtils.LoadAnimation(Resource.Animation.wobble))
. Więcej szczegółów tutaj i tutaj .Ładna animacja potrząsania ;
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>
Jak tego użyć
final Animation animShake = AnimationUtils.loadAnimation(this, R.anim.shake); btn_done = (Button) findViewById(R.id.btn_act_confirm_done); btn_done.startAnimation(animShake);
Jak z niego korzystać (prostsza wersja):
btn_done.startAnimation(AnimationUtils.loadAnimation(this,R.anim.shake));
źródło
android:duration="50"
wygląda na mniej wzburzony moim zdaniem i wygląda muich lepiejMożesz spróbować tego:
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" />
cycle_7.xml
<cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="7" />
źródło
cycle_7.xml
można go zastąpićandroid:repeatCount="7"
atrybutem<translate .../>
spróbuj użyć tego:
<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>
źródło
Aby uzyskać taki efekt wstrząsu
Najpierw zdefiniuj animację potrząśnięcia w folderze anim jako 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>
Następnie w kodzie
if (TextUtils.isEmpty(phone.getText()) || phone.getText().length() < 10) { //shake animation phone.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.shake)); }
źródło
Stworzyłem efekt wstrząsu na Androida i opublikowałem na GitHubie. Sprawdź, czy działa lepiej.
https://github.com/teoinke/ShakeAnimation
Odpowiedni kod:
<?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>
źródło
Ten działa całkiem nieźle (choć nie idealnie) jako klon do wstrząsania „nieprawidłowym kodem PIN” 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();
źródło
/** * * @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; }
posługiwać się:
TextView tv; makeMeShake(tv,20,5); // it will shake quite fast
źródło
Stworzyłem bardzo dobre przybliżenie drgań iOS (gdy długo naciskasz ikonę, aby usunąć aplikację z ekranu głównego). Musisz aplikować wewnątrz swojego kodu, programowo, ponieważ wymaga to generowania liczb losowych:
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);
Ten kod został zaprojektowany do zastosowania w widoku siatki adaptera (getView), ale można go zastosować do dowolnego widoku, zmieniając ostatni wiersz na:
yourViewName.setAnimations (s);
źródło
itemView
nie został jeszcze dodany do ViewGroup. Jeśli został już dodany, użyjitemView.startAnimation(s)
zamiast tego.Dla użytkowników Kotlin:
Najpierw utwórz plik zasobów animacji o nazwie shake.xml . Kliknij prawym przyciskiem myszy folder res w Android Studio, a następnie kliknij Nowy> Plik zasobów systemu Android> wprowadź wstrząsnąć jako nazwę pliku i wybierz Animacja dla rozwijanego typu zasobu. Kliknij OK.
Wewnątrz
shake.xml
wklej następujące elementy:<?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>
Teraz po prostu wywołaj widok!
Z fragmentu:
myView.startAnimation(AnimationUtils.loadAnimation(view!!.context, R.anim.shake))
Z poziomu działania:
myView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake))
(Uwaga -
myView
to identyfikator nadany widokowi, który chcesz animować)Jeśli chcesz dopracować animację, po prostu zmodyfikuj wartości w
shake.xml
.źródło
startAnimation
ianim
(w obrębieR.anim.shake
) są nierozwiązanymi odwołaniami, czy możesz pomóc? dziękiAnimacja chybotania w iOS nie jest taka prosta, próba losowej zmiany osi xiy podczas obracania. Jednak powinieneś zmienić tę wartość programowo. Być może możesz jednocześnie użyć animacji tłumaczenia
źródło
Uderzając głową przez ponad dwie godziny, wiedziałem, jak potrząsać i chybotać widok.
Niestety zaakceptowana odpowiedź nie będzie działać poza onCreateView fragmentu.
Przykład, jeśli masz metodę onClick i wewnątrz niej. Masz animację jak poniżej, ale nie zadziała.
Proszę przejść przez kod.
DoneStart.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { register(view); } });
Metoda rejestracji ma pewne kontrole, takie jak poniższy kod
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(); }
Call animationServiceList.start (); nigdy nie zostanie wezwany,
ROZWIĄZANIE: Użyj PropertyAnimator jak ObjectAnimator.
źródło
Inne odpowiedzi również są poprawne, ale jest to nieco płynniejsze niż one, ponieważ używa interpolatora, który generuje płynne liczby dla ruchu w przód iw tył
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); } }
źródło