如何在BaseActivity中用ProgressBar替代已废弃的ProgressDialog并跨页面复用?
用全局可复用ProgressBar替代废弃的ProgressDialog
嘿,这个问题我太有发言权了!自从API 26把ProgressDialog标为废弃后,我帮好几个项目迁移成了更灵活的全局ProgressBar方案,完美匹配你原来BaseActivity的简洁用法,还能无缝覆盖所有Activity和Fragment。
核心思路
我们不再依赖系统的ProgressDialog,而是自己实现一个覆盖整个屏幕的全局进度条视图,把它嵌入到每个Activity的根布局中,通过BaseActivity统一管理显示/隐藏逻辑,Fragment则通过关联的BaseActivity调用这些方法。
步骤1:创建全局进度条布局
先在res/layout下新建layout_progress_overlay.xml,这个布局会作为遮罩覆盖整个屏幕,中间放置ProgressBar:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/ll_progress_overlay" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/black_50" <!-- 半透明黑色背景,可自定义 --> android:clickable="true" <!-- 防止点击穿透到下层视图 --> android:focusable="true" android:visibility="gone"> <!-- 默认隐藏 --> <!-- 可自定义ProgressBar样式,比如换颜色、加文字 --> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:indeterminate="true" android:theme="@style/CustomProgressBar" /> <!-- 自定义主题,比如修改进度条颜色 --> </FrameLayout>
步骤2:在BaseActivity中实现全局控制逻辑
把原来的ProgressDialog替换成我们的自定义进度条,统一管理显示和隐藏:
public abstract class BaseActivity extends AppCompatActivity { private View mProgressOverlay; private boolean mIsLoading = false; // 记录加载状态,防止旋转屏幕丢失 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initProgressOverlay(); // 恢复屏幕旋转前的加载状态 if (savedInstanceState != null) { mIsLoading = savedInstanceState.getBoolean("KEY_LOADING_STATE"); if (mIsLoading) { showLoading(); } } } private void initProgressOverlay() { // 获取Activity的根视图容器 ViewGroup rootContainer = (ViewGroup) getWindow().getDecorView().findViewById(android.R.id.content); // 加载进度条布局并添加到根容器 mProgressOverlay = LayoutInflater.from(this).inflate(R.layout.layout_progress_overlay, rootContainer, false); rootContainer.addView(mProgressOverlay); } /** * 显示全局加载进度 */ public void showLoading() { if (mProgressOverlay != null && mProgressOverlay.getVisibility() != View.VISIBLE) { mProgressOverlay.setVisibility(View.VISIBLE); mIsLoading = true; } } /** * 隐藏全局加载进度 */ public void hideLoading() { if (mProgressOverlay != null && mProgressOverlay.getVisibility() == View.VISIBLE) { mProgressOverlay.setVisibility(View.GONE); mIsLoading = false; } } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存加载状态,避免屏幕旋转后进度条消失 outState.putBoolean("KEY_LOADING_STATE", mIsLoading); } @Override protected void onDestroy() { super.onDestroy(); // 清理视图,避免潜在内存泄漏 if (mProgressOverlay != null && mProgressOverlay.getParent() != null) { ((ViewGroup) mProgressOverlay.getParent()).removeView(mProgressOverlay); mProgressOverlay = null; } } }
步骤3:让Fragment也能复用这个逻辑
创建BaseFragment,通过关联的BaseActivity调用加载方法,这样所有Fragment都能轻松使用全局进度条:
public abstract class BaseFragment extends Fragment { protected void showLoading() { if (getActivity() instanceof BaseActivity) { ((BaseActivity) getActivity()).showLoading(); } } protected void hideLoading() { if (getActivity() instanceof BaseActivity) { ((BaseActivity) getActivity()).hideLoading(); } } }
额外优化建议
- 自定义样式:可以给ProgressBar设置自定义drawable或者主题,让它和你的App风格统一,比如修改进度条颜色、添加加载文字(只需在布局里加TextView,再在BaseActivity里重载
showLoading(String text)方法)。 - 防止重复调用:我们已经通过
mIsLoading状态变量避免了重复显示/隐藏,你也可以根据需求添加防抖逻辑。 - 处理配置变化:通过
onSaveInstanceState保存加载状态,解决了屏幕旋转后进度条消失的问题,比原来的ProgressDialog更稳定。
这个方案和你原来的BaseActivity用法几乎完全一致,不需要修改业务代码的调用逻辑,就能无缝替换废弃的ProgressDialog,还能获得更灵活的样式控制和更稳定的表现。
内容的提问来源于stack exchange,提问作者Haris Ribic
相关产品推荐
相关产品推荐

