@@ -32,23 +32,24 @@ import java.util.*
3232/* *
3333 * @author Dylan Cai
3434 */
35- class LoadingStateView (private val contentView : View ) {
35+ class LoadingStateView @JvmOverloads constructor(
36+ private val contentView : View ,
37+ var onReloadListener : OnReloadListener ? = null
38+ ) {
3639 lateinit var decorView: View private set
3740 lateinit var currentViewType: Any private set
3841 private lateinit var contentParent: ViewGroup
3942 private val parent: ViewGroup ?
4043 private var currentView: View ? = null
41- private var onReloadListener: OnReloadListener ? = null
4244 private var viewDelegates: HashMap <Any , ViewDelegate > = HashMap ()
4345 private val viewCashes: HashMap <Any , View > = HashMap ()
4446
4547 /* *
46- * Constructs a LoadingStateView with a activity and a content view delegate
47- *
48- * @param activity the activity
48+ * Constructs a LoadingStateView with an activity
4949 */
50- constructor (activity: Activity ) :
51- this (activity.findViewById<ViewGroup >(android.R .id.content).getChildAt(0 ))
50+ @JvmOverloads
51+ constructor (activity: Activity , listener: OnReloadListener ? = null ) :
52+ this (activity.findViewById<ViewGroup >(android.R .id.content).getChildAt(0 ), listener)
5253
5354 init {
5455 viewDelegatePool?.apply { ViewDelegatePool (this @LoadingStateView).invoke() }
@@ -57,6 +58,17 @@ class LoadingStateView(private val contentView: View) {
5758 setDecorView(LinearDecorViewDelegate (emptyList()))
5859 }
5960
61+ /* *
62+ * Adds one or more views to decorate content in the header.
63+ *
64+ * @param delegates the view delegates of creating view
65+ */
66+ fun setHeaders (vararg delegates : ViewDelegate ) =
67+ setDecorView(LinearDecorViewDelegate (delegates.map {
68+ register(it)
69+ getView(it.viewType)
70+ }))
71+
6072 /* *
6173 * Sets an view delegate for decorating content view.
6274 *
@@ -82,12 +94,12 @@ class LoadingStateView(private val contentView: View) {
8294 }
8395
8496 /* *
85- * Adds one or more views to decorate content in the header .
97+ * Adds child decorative header between the content and the decorative view .
8698 *
8799 * @param delegates the view delegates of creating view
88100 */
89- fun setDecorHeader (vararg delegates : ViewDelegate ) =
90- setDecorView (LinearDecorViewDelegate (delegates.map {
101+ fun addChildHeaders (vararg delegates : ViewDelegate ) =
102+ addChildDecorView (LinearDecorViewDelegate (delegates.map {
91103 register(it)
92104 getView(it.viewType)
93105 }))
@@ -106,17 +118,6 @@ class LoadingStateView(private val contentView: View) {
106118 showView(ViewType .CONTENT )
107119 }
108120
109- /* *
110- * Adds child decorative header between the content and the decorative view.
111- *
112- * @param delegates the view delegates of creating view
113- */
114- fun addChildDecorHeader (vararg delegates : ViewDelegate ) =
115- addChildDecorView(LinearDecorViewDelegate (delegates.map {
116- register(it)
117- getView(it.viewType)
118- }))
119-
120121 private fun DecorViewDelegate.createDecorView () =
121122 onCreateDecorView(LayoutInflater .from(contentView.context)).also { decorView ->
122123 contentView.layoutParams?.let { decorView.layoutParams = it }
@@ -125,21 +126,12 @@ class LoadingStateView(private val contentView: View) {
125126 /* *
126127 * Registers the view delegate of creating view before showing view.
127128 *
128- * @param viewDelegate the view delegate of creating view
129+ * @param delegates the view delegate of creating view
129130 */
130131 fun register (vararg delegates : ViewDelegate ) {
131132 delegates.forEach { viewDelegates[it.viewType] = it }
132133 }
133134
134- /* *
135- * Called if you need to handle reload event, you can get the listener of reloading data from view holder.
136- *
137- * @param onReloadListener the listener of reloading data
138- */
139- fun setOnReloadListener (onReloadListener : OnReloadListener ) {
140- this .onReloadListener = onReloadListener
141- }
142-
143135 @JvmOverloads
144136 fun showLoadingView (animation : Animation ? = null) = showView(ViewType .LOADING , animation)
145137
@@ -163,21 +155,25 @@ class LoadingStateView(private val contentView: View) {
163155 if (currentView == null ) {
164156 addView(viewType)
165157 } else {
166- viewCashes[viewType]?. let { addView(viewType) }
158+ if ( viewCashes[viewType] == null ) addView(viewType)
167159 if (viewType != currentViewType) {
168- getView(viewType).visibility = View .VISIBLE
160+ val view = getView(viewType)
161+ view.visibility = View .VISIBLE
169162 if (animation != null ) {
170163 animation.onStartHideAnimation(currentView, currentViewType)
171- animation.onStartShowAnimation(getView(viewType) , getViewDelegate<ViewDelegate >(viewType).viewType)
164+ animation.onStartShowAnimation(view , getViewDelegate<ViewDelegate >(viewType).viewType)
172165 } else {
173166 currentView.visibility = View .GONE
174167 }
175- this .currentView = getView(viewType)
168+ this .currentView = view
176169 }
177170 }
178171 currentViewType = viewType
179172 }
180173
174+ @Suppress(" UNCHECKED_CAST" )
175+ fun <T : ViewDelegate > getViewDelegate (viewType : Any ) = viewDelegates[viewType] as T
176+
181177 private fun addView (viewType : Any ) {
182178 val view = getView(viewType)
183179 if (view.parent != null ) {
@@ -195,21 +191,14 @@ class LoadingStateView(private val contentView: View) {
195191
196192 private fun getView (viewType : Any ): View {
197193 if (viewCashes[viewType] == null ) {
198- addViewHolder(viewType)
194+ val viewDelegate: ViewDelegate = getViewDelegate(viewType)
195+ val view = viewDelegate.onCreateView(LayoutInflater .from(contentParent.context), contentParent)
196+ viewDelegate.onReloadListener = onReloadListener
197+ viewCashes[viewType] = view
199198 }
200199 return viewCashes[viewType]!!
201200 }
202201
203- @Suppress(" UNCHECKED_CAST" )
204- fun <T : ViewDelegate > getViewDelegate (viewType : Any ) = viewDelegates[viewType] as T
205-
206- private fun addViewHolder (viewType : Any ) {
207- val viewDelegate: ViewDelegate = getViewDelegate(viewType)
208- val view = viewDelegate.onCreateView(LayoutInflater .from(contentParent.context), contentParent)
209- viewDelegate.onReloadListener = onReloadListener
210- viewCashes[viewType] = view
211- }
212-
213202 abstract class ViewDelegate (val viewType : Any ) {
214203 var onReloadListener: OnReloadListener ? = null
215204 internal set
@@ -223,7 +212,6 @@ class LoadingStateView(private val contentView: View) {
223212
224213 abstract class DecorViewDelegate {
225214 abstract fun onCreateDecorView (inflater : LayoutInflater ): View
226-
227215 abstract fun getContentParent (decorView : View ): ViewGroup
228216 }
229217
@@ -246,17 +234,12 @@ class LoadingStateView(private val contentView: View) {
246234 fun register (vararg delegates : ViewDelegate ) = stateView.register(* delegates)
247235 }
248236
249- fun interface OnReloadListener {
250- fun onReload ()
251- }
252-
253237 fun interface Callback <in T > {
254238 fun T.invoke ()
255239 }
256240
257241 interface Animation {
258242 fun onStartShowAnimation (view : View , viewType : Any )
259-
260243 fun onStartHideAnimation (view : View , viewType : Any )
261244 }
262245
@@ -270,6 +253,10 @@ class LoadingStateView(private val contentView: View) {
270253 }
271254}
272255
256+ fun interface OnReloadListener {
257+ fun onReload ()
258+ }
259+
273260enum class ViewType {
274261 TITLE , LOADING , CONTENT , ERROR , EMPTY
275262}
0 commit comments