在Android中摇动/摆动查看动画


82

我创建了一个anim.xml文件(例如以下文件)以摇动imageview,例如android中的IOS图标。但是,它不能为我提供相同的结果。有更好的主意吗?

<?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" />

Answers:


171

尝试设置android:repeatMode="reverse"。下面的动画在我的Galaxy Nexus上给出了非常合理的模仿效果。显然,您可以根据自己的喜好对参数进行微调。

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fromDegrees="-5"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toDegrees="5" />

我是Android开发的新手,正在使用Xamarin,请告诉我如何在任何事件(如单击等)下将此动画应用于图像/按钮
NK

@NK:它的工作方式与Java中相同:通过其资源ID加载动画,并通过将其作为参数传递来告诉视图启动动画。应该是这个样子:view.StartAnimation(AnimationUtils.LoadAnimation(Resource.Animation.wobble))这里这里有更多细节。
MH。

3
我们如何增加抖动之间的延迟。例如显示震动500毫秒,然后延迟1000毫秒,然后再次重复?
Damir Mailybayev

73

漂亮的摇动动画;

RES /动画/shakes.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>

如何使用它

final Animation animShake = AnimationUtils.loadAnimation(this, R.anim.shake);
btn_done = (Button) findViewById(R.id.btn_act_confirm_done); 
btn_done.startAnimation(animShake);

使用方法(简单版):

btn_done.startAnimation(AnimationUtils.loadAnimation(this,R.anim.shake));

2
android:duration="50"看起来在我看来,这样少波涛汹涌和外观muich更好
抗体

45

您可以尝试以下方法:

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" />

9
嘿,我想cycle_7.xml可以代替这个android:repeatCount="7"属性<translate .../>
Anup

28

尝试使用这个:

<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>

19

像这样制作震动效果

在此处输入图片说明

首先将anim文件夹内的震动动画定义为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>

然后在代码中

if (TextUtils.isEmpty(phone.getText())
 || phone.getText().length() < 10)
    {
     //shake animation
    phone.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.shake));
     }

14

我在Android上创建了震动效果,并发布在GitHub上。看看它是否更好。

https://github.com/teoinke/ShakeAnimation

相关代码:

<?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>

1
对我来说,这是最好的答案,因为它是从中心动画的,不会像其他一些建议那样立即使图像偏移。亲!
乔纳森·邓恩

13

这个作为iOS“不正确的PIN”摇动克隆的效果很好(尽管不是很完美):

    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();

5
/**
 *
 * @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;
}

使用:

TextView tv;
makeMeShake(tv,20,5);    // it will shake quite fast

完美且快速地工作。
乔治Vrynios

3

我创建了一个很好的iOS震动近似值(当您长按一个图标从主屏幕删除应用程序时)。您必须以编程方式应用代码内部,因为它需要生成随机数:

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);

该代码设计为应用于适配器的gridview(getView)内部,但是您可以通过将最后一行更改为以下内容来应用于任何视图:

yourViewName.setAnimations(s);


似乎什么也没做
user25

请记住,这仅itemView在尚未添加到ViewGroup中时才起作用。如果已添加,请itemView.startAnimation(s)改用。
Alex Semeniuk

2

对于Kotlin用户:

首先创建一个动画资源文件,名为shake.xml。右键单击Android Studio中的res文件夹,然后单击新建> Android资源文件>输入震动作为文件名,然后为资源类型下拉列表选择动画。单击确定。

在内部shake.xml粘贴以下内容:

<?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>

现在,只需在视图上调用它即可!

从片段中:

myView.startAnimation(AnimationUtils.loadAnimation(view!!.context, R.anim.shake))

从活动中:

myView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.shake))

(注意-myView是给您要设置动画的视图的ID)

如果您想微调动画,只需修改中的值shake.xml


startAnimationanim(中的R.anim.shake)都是未解决的参考,请您能帮忙吗?谢谢
马夫

您需要在res目录@Maff中创建一个anim文件夹
Aditya Patil

0

iOS摆动动画并不是那么简单,尝试在旋转时随机更改枢轴x和y。但是,您应该以编程方式更改该值。可能您也可以同时使用翻译动画


0

敲打我的头两个多小时,我知道如何摇晃和摆动视图。

不幸的是,除了片段的onCreateView之外,可接受的答案无法正常工作。

例如,如果您具有onClick方法及其内部。您的动画如下所示,将无法使用。

请检查代码。

    DoneStart.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {
           register(view);

        }
    });

register方法有一些检查,如下面的代码

 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();
    }

调用animationServiceList.start(); 永远不会被呼唤

解决方案:使用ObjectAnimator之类的PropertyAnimator。


0

其他答案也都是正确的,但这比它们要平滑一些,因为它使用插值器来产生平滑数字以进行来回移动

    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);
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.