|
| 1 | +## 基础用法 |
| 2 | + |
| 3 | +使用 Kotlin 开发的话推荐用委托的用法,不过建议先把基础的 `LoadingStateView` 用法看了。 |
| 4 | + |
| 5 | +### 显示加载中、加载失败等缺省页 |
| 6 | + |
| 7 | +第一步,使用 Activity 或 View 创建 `LoadingStateView`,不需要重新加载的话 `OnReloadListener` 可不传。 |
| 8 | + |
| 9 | +```kotlin |
| 10 | +val loadingStateView = LoadingStateView(this, onReloadListener) |
| 11 | +// val loadingStateView = LoadingStateView(view, onReloadListener) |
| 12 | +``` |
| 13 | + |
| 14 | +第二步,创建一个类继承 `LoadingStateView.ViewDelegate`。 |
| 15 | + |
| 16 | +构造函数需要传个参数,决定视图类型,之后显示和更新会用到。默认提供了 `ViewType.LOADING`、`ViewType.ERROR`、`ViewType.EMPTY`、`ViewType.TITLE`,其它的可以用一个 String 作为类型。 |
| 17 | + |
| 18 | +```kotlin |
| 19 | +class LoadingViewDelegate : LoadingStateView.ViewDelegate(ViewType.LOADING) { |
| 20 | + |
| 21 | + override fun onCreateView(inflater: LayoutInflater, parent: ViewGroup): View = |
| 22 | + inflater.inflate(R.layout.layout_loading, parent, false) |
| 23 | +} |
| 24 | +``` |
| 25 | + |
| 26 | +如果需要实现点击重新请求数据,可以在点击事件调用 `onReloadListener?.onReload()` 方法。 |
| 27 | + |
| 28 | +第三步,注册 `ViewDelegate`。首先在 Application 注册全局的 `ViewDelegate`: |
| 29 | + |
| 30 | +```kotlin |
| 31 | +LoadingStateView.setViewDelegatePool { |
| 32 | + register(LoadingViewDelegate(), ErrorViewDelegate(), EmptyViewDelegate()) |
| 33 | +} |
| 34 | +``` |
| 35 | + |
| 36 | +如果某个页面需要不同样式,就用该页面的 `LoadingStateView` 注册对应类型的 `ViewDelegate`,就可以把全局的替换了。 |
| 37 | + |
| 38 | +```kotlin |
| 39 | +loadingStateView.register(CoolLoadingViewDelegate()) |
| 40 | +``` |
| 41 | + |
| 42 | +第四步,显示对应类型的视图。 |
| 43 | + |
| 44 | +```kotlin |
| 45 | +loadingStateView.showView(viewType) |
| 46 | +loadingStateView.showLoadingView() // 显示 ViewType.LOADING 类型的视图 |
| 47 | +loadingStateView.showContentView() // 显示 ViewType.CONTENT 类型的视图 |
| 48 | +loadingStateView.showErrorView() // 显示 ViewType.ERROR 类型的视图 |
| 49 | +loadingStateView.showEmptyView() // 显示 ViewType.EMPTY 类型的视图 |
| 50 | +``` |
| 51 | + |
| 52 | +### 更新视图样式 |
| 53 | + |
| 54 | +需要在 `ViewDelegate` 自行实行更新的方法,然后获取到对应的 `ViewDelegate` 进行更新。 |
| 55 | + |
| 56 | +比如在 `ErrorViewDelegate` 增加了 `updateMsg(msg)` 方法修改请求失败的文字: |
| 57 | + |
| 58 | +```kotlin |
| 59 | +loadingStateView.getViewDelegate<ErrorViewDelegate>(ViewType.ERROR).updateMsg("服务器繁忙,请稍后重试") |
| 60 | +``` |
| 61 | + |
| 62 | +### 在内容上方添加视图 |
| 63 | + |
| 64 | +实现标题栏或搜索栏等 `ViewDelegate`,之后就可以用 `LoadingStateView` 在内容布局的上方添加视图。 |
| 65 | + |
| 66 | +```kotlin |
| 67 | +loadingStateView.setHeaders(ToolbarViewDelegate("消息"), SearchViewDelegate()) |
| 68 | +``` |
| 69 | + |
| 70 | +### 给内容的外层增加装饰布局 |
| 71 | + |
| 72 | +可以给内容布局添加一层装饰,实现更复杂的样式,非简单地在头部增加控件,比如带联动效果的标题栏、DrawerLayout、底部输入框等布局。 |
| 73 | + |
| 74 | +我们来实现滑动隐藏标题栏的效果,写一个带联动效果的标题栏布局,其中有个 FragmentLayout 是用于填充内容和切换缺省页。 |
| 75 | + |
| 76 | +```xml |
| 77 | +<?xml version="1.0" encoding="utf-8"?> |
| 78 | +<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| 79 | + xmlns:app="http://schemas.android.com/apk/res-auto" |
| 80 | + android:layout_width="match_parent" |
| 81 | + android:layout_height="match_parent"> |
| 82 | + |
| 83 | + <com.google.android.material.appbar.AppBarLayout |
| 84 | + android:id="@+id/app_bar" |
| 85 | + android:layout_width="match_parent" |
| 86 | + android:layout_height="wrap_content" |
| 87 | + android:elevation="2dp"> |
| 88 | + |
| 89 | + <androidx.appcompat.widget.Toolbar |
| 90 | + android:id="@+id/toolbar" |
| 91 | + android:layout_width="match_parent" |
| 92 | + android:layout_height="?attr/actionBarSize" |
| 93 | + app:layout_collapseMode="pin" |
| 94 | + app:layout_scrollFlags="scroll|enterAlways" |
| 95 | + app:navigationIcon="@drawable/ic_arrow_back_ios" |
| 96 | + android:background="@color/white" |
| 97 | + app:titleTextAppearance="@style/ToolbarTextAppearance" /> |
| 98 | + |
| 99 | + </com.google.android.material.appbar.AppBarLayout> |
| 100 | + |
| 101 | + <FrameLayout |
| 102 | + android:id="@+id/content_parent" |
| 103 | + android:layout_width="match_parent" |
| 104 | + android:layout_height="match_parent" |
| 105 | + app:layout_behavior="@string/appbar_scrolling_view_behavior"/> |
| 106 | + |
| 107 | +</androidx.coordinatorlayout.widget.CoordinatorLayout> |
| 108 | +``` |
| 109 | + |
| 110 | +然后写一个类继承 `LoadingStateView.DecorViewDelegate`。 |
| 111 | + |
| 112 | +```kotlin |
| 113 | +class ScrollingDecorViewDelegate(private val title: String) : LoadingStateView.DecorViewDelegate() { |
| 114 | + |
| 115 | + override fun onCreateDecorView(context: Context, inflater: LayoutInflater): View { |
| 116 | + val view = inflater.inflate(R.layout.layout_scrolling_toolbar, null) |
| 117 | + val toolbar: Toolbar = view.findViewById(R.id.toolbar) |
| 118 | + toolbar.title = title |
| 119 | + toolbar.setNavigationOnClickListener { |
| 120 | + if (context is Activity) context.finish() |
| 121 | + } |
| 122 | + return view |
| 123 | + } |
| 124 | + |
| 125 | + override fun getContentParent(decorView: View): ViewGroup { |
| 126 | + return decorView.findViewById(R.id.content_parent) |
| 127 | + } |
| 128 | +} |
| 129 | +``` |
| 130 | + |
| 131 | +与 `ViewDelegate` 不同的是,需要多实现一个 `getContentParent(decorView)` 方法来指定添加内容的容器,这里我们返回前面的 FrameLayout。 |
| 132 | + |
| 133 | +之后就可以给内容进行装饰了。 |
| 134 | + |
| 135 | +```kotlin |
| 136 | +loadingStateView.setDecorView(ScrollingDecorViewDelegate("Test")) |
| 137 | +``` |
0 commit comments