You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android中如何在动画执行时改变View的尺寸?

实现环形进度条+文本的过渡动画(Android Fragment)

我刚在Android Studio的Fragment里搞定了一个从100%平滑过渡到目标值的动画效果,用到了自定义环形进度条和同步更新的文本,把实现过程整理出来给你参考:

1. 自定义环形ProgressBar的Drawable

首先是你用到的环形Drawable文件,我把代码和每个属性的作用拆解一下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:useLevel="true"
    android:innerRadiusRatio="2.3"
    android:shape="ring"
    android:thickness="8sp" >

    <solid android:color="@color/colorPrimary" />
</shape>
  • android:useLevel="true":这个是核心属性,必须开启才能让Shape跟着ProgressBar的进度值动态显示环形长度
  • android:innerRadiusRatio="2.3":控制环形内半径的比例,数值越小内半径越大,2.3的比例会让环形视觉上更协调
  • android:thickness="8sp":设置环形的厚度,用sp单位能适配不同屏幕的文字缩放规则
  • <solid>标签:定义环形的填充色,这里直接用了项目的主题色colorPrimary

2. Fragment中的动画实现逻辑

在Fragment的生命周期方法(比如onViewCreated)里,我们可以通过ValueAnimator实现从100%到目标值的平滑过渡,同时同步更新ProgressBar和TextView:

先看布局中的控件示例

<!-- 环形进度条 -->
<ProgressBar
    android:id="@+id/circular_progress"
    android:layout_width="120dp"
    android:layout_height="120dp"
    style="?android:attr/progressBarStyleHorizontal"
    android:progressDrawable="@drawable/你的环形Drawable文件名" />

<!-- 进度文本 -->
<TextView
    android:id="@+id/progress_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="100%"
    android:textSize="18sp" />

Kotlin版本代码

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    val circularProgress = view.findViewById<ProgressBar>(R.id.circular_progress)
    val progressText = view.findViewById<TextView>(R.id.progress_text)
    val targetProgress = 65 // 替换成你需要的目标数值

    // 创建从100到目标值的数值动画
    val animator = ValueAnimator.ofInt(100, targetProgress)
    animator.duration = 1500 // 动画时长,单位毫秒
    animator.addUpdateListener { animation ->
        val currentProgress = animation.animatedValue as Int
        // 更新进度条
        circularProgress.progress = currentProgress
        // 更新文本
        progressText.text = "$currentProgress%"
    }
    // 启动动画
    animator.start()
}

Java版本代码

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    
    ProgressBar circularProgress = view.findViewById(R.id.circular_progress);
    TextView progressText = view.findViewById(R.id.progress_text);
    int targetProgress = 65; // 目标进度值

    ValueAnimator animator = ValueAnimator.ofInt(100, targetProgress);
    animator.setDuration(1500);
    animator.addUpdateListener(animation -> {
        int currentProgress = (int) animation.getAnimatedValue();
        circularProgress.setProgress(currentProgress);
        progressText.setText(currentProgress + "%");
    });
    animator.start();
}

额外优化小提示

  • 记得给ProgressBar设置style="?android:attr/progressBarStyleHorizontal",否则自定义的环形Drawable不会生效
  • 如果想要动画过渡更自然,可以添加插值器,比如animator.interpolator = AccelerateDecelerateInterpolator(),让动画先加速后减速
  • 目标值如果是动态获取的(比如接口返回),直接把targetProgress替换成对应变量即可

内容的提问来源于stack exchange,提问作者bleand

火山引擎 最新活动