【问题标题】:How to create a drawable right animation button如何创建可绘制的右动画按钮
【发布时间】:2021-07-13 15:48:41
【问题描述】:

如何创建一个正确的旋转按钮动画,我尝试了下面的代码,但它一直在崩溃。

button_spin_animation.xml

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

用法

 @Override
    public void onStart() {
        super.onStart();

        account_login.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(getApplicationContext(), R.drawable.button_spin_animation), null);
        Drawable[] sb = account_login.getCompoundDrawables();
        AnimationDrawable animDrawable = (AnimationDrawable) sb[0];
        animDrawable.start();
    }

错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.app.android.buyer/com.app.android.buyer.Login}: android.content.res.Resources$NotFoundException: Drawable 
     Caused by: android.content.res.Resources$NotFoundException: Drawable com.app.android.buyer:drawable/button_spin_animation with resource ID #0x7f080146
     Caused by: android.content.res.Resources$NotFoundException: File res/drawable/button_spin_animation.xml from drawable resource ID #0x7f080146
        at 
     Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #8: <rotate> tag requires a 'drawable' attribute or child tag defining a drawable
        at android.graphics.drawable.RotateDrawable.verifyRequiredAttributes(RotateDrawable.java:106)
        at android.graphics.drawable.RotateDrawable.inflate(RotateDrawable.java:76)
        at android.graphics.drawable.DrawableInflater.inflateFromXmlForDensity(DrawableInflater.java:145)
        at android.graphics.drawable.Drawable.createFromXmlInnerForDensity(Drawable.java:1295)
        at android.graphics.drawable.Drawable.createFromXmlForDensity(Drawable.java:1254)
        at 

【问题讨论】:

    标签: android android-animation drawable


    【解决方案1】:

    您需要进行 3 项更改:

    1. 将drawable添加到您的button_spin_animation
    2. 如果您想获得正确的可绘制对象,请使用第二个索引。
    3. 使用ObjectAnimator 为您的drawable 设置动画。

    以下是您的用例示例:

    Java file:

    public class MainActivity extends AppCompatActivity {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            TextView tv = findViewById(R.id.tv);
    
            tv.setCompoundDrawablesWithIntrinsicBounds(
                    null,
                    null,
                    ContextCompat.getDrawable(getApplicationContext(), R.drawable.button_spin_animation),
                    null
            );
    
            int MAX_LEVEL = 10000;
    
            Drawable[] sb = tv.getCompoundDrawables();
    
            ObjectAnimator anim = ObjectAnimator.ofInt(sb[2], "level", 0, MAX_LEVEL);
            anim.start();
    
        }
    
    }
    

    button_spin_animation.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
        android:drawable="@drawable/ic_add"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:toDegrees="360" />
    

    用你的drawable替换ic_add

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        
    
        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
    

    【讨论】:

    • 我使用了您的示例,将ic_add 替换为图像,它在我的按钮右侧显示图像但它不旋转。
    • @Peter 您想无限次旋转它还是想旋转一段时间?因为我目前的实现非常快。它旋转并回到原来的位置。可以设置anim.setDuration(10000);查看效果。
    【解决方案2】:

    我为您编写了一个解决方案。 MainActivity.java 类包含 2 个函数,它们将运行动画并停止它。看这里:

    public class MainActivity extends AppCompatActivity {
    
        public static ImageView ImageIcon;
        public static boolean aBoolean = false;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ImageIcon = findViewById(R.id.imageView);
            Button button = findViewById(R.id.btn);
            button.setOnClickListener(v -> {
                if(!aBoolean) {
                    runBtnAnimation();
                    aBoolean = true;
                }
                else {
                    stopBtnAnimation();
                    aBoolean = false;
                }
            });
            
        }
    
        private void runBtnAnimation() {
            ImageIcon.setImageResource(R.drawable.ic_baseline_flutter_dash_24);
            Animation rotation = AnimationUtils
                    .loadAnimation(getApplicationContext(),
                            R.anim.rotation_animation);
            ImageIcon.startAnimation(rotation);
        }
    
        private void stopBtnAnimation() {
            ImageIcon.clearAnimation();
            ImageIcon.setImageResource(R.drawable.ic_baseline_flutter_dash_24);
        }
    }
    

    之后,您将创建activity_main.xml 布局。我想指出的是,您需要将ButtonImageView 以不同的elevation 级别放在彼此之上,放入frame(此处为FrameLayout):

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <FrameLayout
            android:id="@+id/frame"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true">
            <Button
                android:id="@+id/btn"
                android:layout_width="200dp"
                android:layout_height="100dp"
                android:elevation="0dp"/>
            <ImageView
                android:id="@+id/imageView"
                android:layout_width="200dp"
                android:layout_height="80dp"
                android:layout_gravity="center"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_baseline_flutter_dash_24"
                android:elevation="4dp"/>
        </FrameLayout>
    </RelativeLayout>
    

    最后一部分是在rotation_animation.xml 中配置动画行为,该res/anim 文件夹位于您的res/anim 文件夹中:

    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:shareInterpolator="false">
        <rotate
            android:duration="1000"
            android:fromDegrees="0"
            android:interpolator="@android:anim/accelerate_decelerate_interpolator"
            android:pivotX="50%"
            android:pivotY="50%"
            android:repeatCount="infinite"
            android:repeatMode="restart"
            android:toDegrees="359"/>
    </set>
    

    结果

    在本例中,ImageView 在被点击后会旋转infinite。再次单击后动画停止,set 是之前的ImageResource。但是您可以随意使用function runBtnAnimation()stopBtnAnimation()。干杯!

    【讨论】:

    • 我正在尝试旋转按钮可绘制的右图像而不是按钮,而且我希望它继续旋转直到我调用`anim.cancel();`
    • 我用您正在寻找的行为更新了我的答案 :) 干杯!
    • 您能否确认答案是正确的,是否知道您需要进一步的帮助?对我来说,在改进解决问题的过程中,是否缺少一些东西?很高兴收到一点反馈。
    猜你喜欢
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-25
    • 1970-01-01
    相关资源
    最近更新 更多