Android开发

Android中如何优雅的显示loading页

2021-01-05  本文已影响0人  双木成林028

先说如何使用

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。

上一篇下一篇

猜你喜欢

热点阅读