设置按钮背景动画以反射(reflect)剩余时间?

2019年9月18日 13点热度 0条评论

我正在开发一个Android项目,用户可以在其中扫描RFID标签。该标签会在一定秒数后过期,以清除另一个标签之前的系统,这基本上是为了避免同一标签被错误地处理两次。为了可视化此超时,我希望对显示标签ID的按钮的背景进行动画处理。基本上,当标签刚刚被扫描时,我希望整个按钮都充满颜色,然后随着时间的推移慢慢缩小到中间。

到目前为止,我发现了什么:
我在他们谈论属性api的地方找到了this answer。我可以看到它与渐变一起使用,但是不幸的是,有关渐变的文档很少,而且看起来很难做到这一点。

我还认为,也许可以通过在按钮下方分层放置另一个相同大小的视图并对其进行缩放来实现此目的。但老实说,我认为要做到一贯地做到这一点非常困难,尤其是在计时器进程和配置更改时调整视图大小时。再说一次,我对Android并没有真正的经验,因为几乎最容易理解它们,所以几乎对所有东西都使用线性和网格布局。

我真正需要的是某种方法,如我在此处演示的那样,通过一个值(总时间与剩余时间之间的比例)将背景从本质上“缩放”到中间。或者是一种基本具有硬色渐变的方法,其中随着时间的推移,渐变的白色部分向中间移动。

我认为可能可行的最后一个解决方案是使动画矢量可绘制并操纵与之关联的对象动画,以使其以正确的速度播放。但是,此解决方案可能非常混乱,以为我还没有尝试过(尚未)

有谁有解决这个问题的干净方法?

注意:我正在为此项目使用Java。我没有包括代码片段,因为我认为它们不是必需的。如果您需要一些摘要,请简单地询问,我会提供。我的minSdkVersion是25,因为作业的目标设备具有android 7.1,并且无法更新到较新的版本。

解决方案如下:

这是一个带有两个进度条和一个文本视图的示例布局:

    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:progressBackgroundTint="@color/transparent"
        android:rotation="180"
        android:scaleY="4"
        app:layout_constraintBottom_toBottomOf="@id/textView2"
        app:layout_constraintEnd_toStartOf="@+id/progressBar2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@id/textView2"
        tools:progress="100" />

    <ProgressBar
        android:id="@+id/progressBar2"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:progressBackgroundTint="@color/transparent"
        android:scaleY="4"
        app:layout_constraintBottom_toBottomOf="@id/textView2"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/progressBar"
        app:layout_constraintTop_toTopOf="@id/textView2"
        tools:progress="100" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="24dp"
        android:text="TextView"
        android:textAlignment="center"
        android:textColor="@color/black"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

这些是将进度设置为100、50和1所得到的结果:

100:

50:

1:

如果您添加自定义可绘制对象作为背景,则可以使进度条相应地填充该空间,并将其颜色设置为红色。

请注意,照片中的灰线来自Android Studio中的“设计”选项卡,除调试时不可见。

更新:这是使进度条在5秒钟内从100%重置为0%的动画代码。

ProgressBar pb = findViewById(R.id.progressBar);

ProgressBar pb2 = findViewById(R.id.progressBar2);

    ObjectAnimator animation = ObjectAnimator.ofInt(pb, "progress", 0, 100);
    animation.setDuration(5000);
    animation.setInterpolator(new DecelerateInterpolator());
    animation.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animator) { }

        @Override
        public void onAnimationEnd(Animator animator) {
            //do something when the countdown is complete
        }

        @Override
        public void onAnimationCancel(Animator animator) { }

        @Override
        public void onAnimationRepeat(Animator animator) { }
    });
    animation.start();

    AnimatorSet set = new AnimatorSet();
    set.playTogether(ObjectAnimator.ofInt(pb, "progress", 100, 0),
            ObjectAnimator.ofInt(pb2, "progress", 100, 0));
    set.setDuration(5000);
    set.start();