如何将Activity自定义为进度页面并在切换时显示GIF与动画?求实现建议
Hey there! Let's walk through exactly how to build that custom progress Activity with GIF/transition animations, plus an adaptive custom progress bar for your Android app. I’ve got practical, code-backed solutions for both parts below:
1.1 基础布局搭建
Start with a full-screen layout that centers your GIF and optional loading text. Use ConstraintLayout for flexible screen adaptation:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <!-- GIF 展示控件 --> <ImageView android:id="@+id/iv_progress_gif" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> <!-- 可选加载提示文本 --> <TextView android:id="@+id/tv_progress_hint" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="加载中..." android:textSize="16sp" android:marginTop="16dp" app:layout_constraintTop_toBottomOf="@id/iv_progress_gif" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"/> </androidx.constraintlayout.widget.ConstraintLayout>
1.2 加载GIF文件
The easiest way to handle GIFs is using Glide (it handles memory management and playback automatically):
// 先在build.gradle中添加Glide依赖:implementation 'com.github.bumptech.glide:glide:4.16.0' Glide.with(this) .asGif() .load(R.raw.loading_animation) // 把GIF放在res/raw目录下 .into(findViewById(R.id.iv_progress_gif))
1.3 添加页面切换动画
Smooth transitions make the progress page feel more polished. First create two animation files in res/anim/:
fade_in.xml(for entering the progress Activity):
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromAlpha="0.0" android:toAlpha="1.0"/>
fade_out.xml(for exiting):
<?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300" android:fromAlpha="1.0" android:toAlpha="0.0"/>
Then apply the animations when starting/finishing the Activity:
// 启动进度Activity时 val intent = Intent(this, ProgressActivity::class.java) startActivity(intent) overridePendingTransition(R.anim.fade_in, R.anim.fade_out) // 在ProgressActivity中关闭时 finish() overridePendingTransition(R.anim.fade_out, R.anim.fade_in)
2.1 完全自定义View(灵活可控)
Build a custom View that combines a GIF background with a progress mask. This gives you full control over appearance:
class GifProgressBar @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 ) : View(context, attrs, defStyleAttr) { private var currentProgress: Float = 0f private var gifDrawable: GifDrawable? = null private val maskPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply { color = Color.parseColor("#80000000") // 半透明黑色遮罩 } init { // 加载GIF背景 Glide.with(context) .asGif() .load(R.raw.progress_bg) .into(object : CustomTarget<GifDrawable>() { override fun onResourceReady(resource: GifDrawable, transition: Transition<in GifDrawable>?) { gifDrawable = resource gifDrawable?.callback = this@GifProgressBar invalidate() } override fun onLoadCleared(placeholder: Drawable?) {} }) } // 设置进度(0-100) fun setProgress(progress: Float) { currentProgress = progress.coerceIn(0f, 100f) invalidate() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) // 绘制GIF背景 gifDrawable?.let { it.setBounds(0, 0, width, height) it.draw(canvas) } // 绘制未完成区域的遮罩 val maskWidth = width * (1 - currentProgress / 100f) canvas.drawRect(width - maskWidth, 0f, width.toFloat(), height.toFloat(), maskPaint) } // 控制GIF播放状态 override fun onVisibilityChanged(changedView: View, visibility: Int) { super.onVisibilityChanged(changedView, visibility) if (visibility == VISIBLE) gifDrawable?.start() else gifDrawable?.stop() } }
Use it in your layout:
<com.yourpackage.GifProgressBar android:id="@+id/custom_progress_bar" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginHorizontal="16dp"/>
Update progress with an animator for smooth effects:
val progressBar = findViewById<GifProgressBar>(R.id.custom_progress_bar) val animator = ValueAnimator.ofFloat(0f, 100f).apply { duration = 2000 addUpdateListener { progressBar.setProgress(it.animatedValue as Float) } } animator.start()
2.2 简化方案:系统ProgressBar + GIF背景
If you don’t need full customization, repurpose the system ProgressBar with GIF layers:
<ProgressBar android:id="@+id/progress_bar" android:layout_width="match_parent" android:layout_height="40dp" android:indeterminate="false" android:progressDrawable="@drawable/progress_gif_layer"/>
Create progress_gif_layer.xml in res/drawable/:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 背景层:GIF --> <item android:id="@android:id/background"> <bitmap android:src="@raw/progress_bg" android:tileMode="repeat"/> </item> <!-- 进度层:GIF或纯色 --> <item android:id="@android:id/progress"> <clip> <bitmap android:src="@raw/progress_fill" android:tileMode="repeat"/> </clip> </item> </layer-list>
- 屏幕适配: Avoid fixed dimensions—use
match_parent,wrap_content, orConstraintLayoutconstraints. For GIFs, usescaleType="centerInside"to prevent stretching on different screen sizes. - 内存优化: Use compressed GIFs (keep file size under 1MB if possible). Glide automatically caches and downsizes GIFs to save memory.
- Full-screen theme: Set your progress Activity to full-screen for a cleaner look:
<activity android:name=".ProgressActivity" android:theme="@style/FullScreenProgressTheme"/>
<style name="FullScreenProgressTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar"> <item name="android:windowFullscreen">true</item> <item name="android:windowContentOverlay">@null</item> </style>
内容的提问来源于stack exchange,提问作者raguM.tech.

