前言
页面多状态布局是开发中常见的需求,即页面在不同状态需要显示不同的布局,实现的方式也比较多,最简单粗暴的方式就是在 XML 中先将不同状态对应的布局隐藏起来,根据需要改变其可见状态,如果多个界面公用相同的状态布局,缺点也很明显,繁琐、重复、不优雅等,类似的实现也可以使用 ViewStub,这样性能会更好些。所以我们要做的就是尽可能避免这些方式所导致的问题,更加高效、优雅的管理不同的状态布局。
传统的做法
-
定义一个(或多个)显示不同加载状态的控件或者xml布局文件(例如:LoadingView)
-
每个页面的布局中都写上这个view
-
在BaseActivity/BaseFragment中封装LoadingView的初始化逻辑,并封装加载状态切换时的UI显示逻辑,暴露给子类以下方法:
void showLoading(); //调用此方法显示加载中的动画 void showContent(); //调用此方法显示主布局 void showEmpty(); //调用此方法显示空页面 void showRetry(); //子类中实现,点击重试的回调方法
这种使用方式耦合度太高,每个页面的布局文件中都需要添加LoadingView,使用起来不方便而且维护成本较高,一旦UI设计师需要更改布局,修改起来成本较高。
MultiPageControl
多布局页面 无侵入布局 为Activity、Fragment、任何View设置等待(loading)、重试(retry)、无数据(empty)页面。
效果图
- 不同状态可随意编辑
如何使用
将其添加到存储库末尾的根build.gradle中:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
步骤2.添加依赖项
dependencies {
implementation 'com.github.long216:MultiPageControl:1.0.2'
}
如果多个页面共享加载和重试页面,建议全局设置个基本的。比如在Application中:
public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
//设置默认3个界面
MultiPageControlManager.defaultLayout(R.layout.base_loading,R.layout.base_retry,R.layout.base_empty);
}
}
使用
public class MainActivity extends AppCompatActivity
{
private MultiPageControlManager mMultiPageControlManager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//为根布局控件
RelativeLayout relativeLayout = findViewById(R.id.mainRelativeLayout);
//如在Application中设置了默认控件且不需要使用别的样式可使用此方法创建
mMultiPageControlManager = MultiPageControlManager.getInstance().init(relativeLayout);
//优先级高于默认设置的布局 会覆盖默认布局
mMultiPageControlManager = MultiPageControlManager.getInstance().init(relativeLayout,R.layout.base_loading,R.layout.base_retry,R.layout.base_empty);
loadData();
}
}
只需要在onCreate中调用MultiPageControlManager.getInstance().init()
即可。
- 可为任何View添加,只需要将对应的View传入第一个参数即可。
点击事件:
public class MainActivity extends AppCompatActivity
{
private MultiPageControlManager mMultiPageControlManager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
//初始化完毕之后(点击事件)
multiPageControlManager.setOnEmptyClickListener(new MultiPageControlManager.OnLoadingAndRetryListener() {
@Override
public void onClick() {
multiPageControlManager.showContent();
}
});
//布局之内子控件点击事件
multiPageControlManager.setOnRetryChildClickListener(R.id.retryButton, new MultiPageControlManager.OnLoadingAndRetryListener() {
@Override
public void onClick() {
multiPageControlManager.showContent();
}
});
loadData();
}
}
API
- defaultLayout(int loadingId, int retryId, int emptyId);
- init(View view);
- init(View view, int loadingId, int retryId, int emptyId);
- showContent();
- showRetry();
- showLoading();
- showEmpty();
- setOnRetryClickListener(final OnLoadingAndRetryListener onRetryClickListener);
- setOnEmptyClickListener(final OnLoadingAndRetryListener onEmptyClickListener);
- setOnEmptyChildClickListener(int id, final OnLoadingAndRetryListener onEmptyChildClickListener);
- setOnRetryChildClickListener(int id, final OnLoadingAndRetryListener onRetryChildClickListener);