Android中如何优雅的显示loading页
先说如何使用
Gradle:
//项目gradle中
allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
}
}
//模块gradle中
implementation 'com.github.goodluck028:ShowLoading:1.0.1'
使用方法
//activity
LoadingShow.with(MainActivity.this).showLoading();
LoadingShow.with(MainActivity.this).dismiss();
//fragment
LoadingShow.with(TestFragment.this).showLoading();
LoadingShow.with(TestFragment.this).dismiss();
//view
TextViewtestView=findViewById(R.id.tv_test_view);
LoadingShow.with(testView).showLoading();
LoadingShow.with(testView).dismiss();
注意事项
在fragment的onCreateView()方法中使用会无效,是由于fragment的加载机制引起的,建议在onResume()方法中使用,后续版本想办法解决。
实现思路
找到需要显示loading页的view,然后把它从View树中打断,再包裹上一个FramLayout,然后再接回原来的View树中。
Actively中的View
网上很多方法是这样的
getWindow().getDecorView().findViewById(android.R.id.content)
我通过以上方法拿到的是个null,可能是和我的Android sdk版本有关。
以v30版sdk的AppCompactActivity为例,我们可以通过
ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
ViewGroup contentRoot = (ViewGroup) decor.getChildAt(0);
ViewGroup bar = (ViewGroup) contentRoot.getChildAt(1);
ActionBarOverlayLayout act = (ActionBarOverlayLayout) bar.getChildAt(0);
View content =null;
try {
content = ((FrameLayout) Reflector.getValue(act, "mContent")).getChildAt(0);
}catch (Exception ex) {
}
层层包裹,最终我们拿到一个ActionBarOverlayLayout,这还不是我们真正想要的view,通过断点调试,我们发现真正的view是一个私有变量mContent。这就好办了,通过反射拿出。至此,我们通过Actively拿到了想要的view。
这里要注意的一点是,可能其它版本的sdk有不同的实现,需要根据实际情况调整以上代码。
Fragment中的view
fragment中的view获取起来是非常简单的。
fragment.getView()
打断view并包裹framelayout
我们要找到原view在父view中的布局参数和index,这个好办:
//替换注入framelayout
mFrameLayout =new FrameLayout(mContentView.getContext());
mFrameLayout.setLayoutParams(mContentView.getLayoutParams());
ViewGroup parent = (ViewGroup)mContentView.getParent();
for (int i =0; i < parent.getChildCount(); i++) {
if (parent.getChildAt(i) == contentView) {
parent.removeView(mContentView);
parent.addView(mFrameLayout, i);
break;
}
}
//嫁接用户view
FrameLayout.LayoutParams lp =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
mContentView.setLayoutParams(lp);
mFrameLayout.addView(mContentView);
显示loading或者error页面
有了前面几步的操作,剩下的就是在注入的framelayout中动态显示自己想要的view了。
FrameLayout.LayoutParams lp =new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
view.setLayoutParams(lp);
mFrameLayout.addView(view);
GitHub地址
https://github.com/goodluck028/ShowLoading
关于我
来自成都的苦逼程序员一枚,样样懂、门门瘟,喜欢金融、喜欢计算机。有bug加我QQ459057268。