Skip to content

Commit 19b5fbb

Browse files
Merge pull request #45 from DylanCaiCoding/5.0.0
5.0.0
2 parents 15c0082 + 49dd022 commit 19b5fbb

File tree

18 files changed

+175
-103
lines changed

18 files changed

+175
-103
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ Add dependencies in your module `build.gradle` :
5555
```groovy
5656
dependencies {
5757
// java
58-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview:4.1.0'
58+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview:5.0.0'
5959
6060
// kotlin
61-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:4.1.0'
61+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:5.0.0'
6262
}
6363
```
6464

README_ZH.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,10 @@ allprojects {
5757
```groovy
5858
dependencies {
5959
// java
60-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview:4.1.0'
60+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview:5.0.0'
6161
6262
// kotlin
63-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:4.1.0'
63+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:5.0.0'
6464
}
6565
```
6666

docs/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ allprojects {
5353
```groovy
5454
dependencies {
5555
// java
56-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview:4.1.0'
56+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview:5.0.0'
5757
5858
// kotlin
59-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:4.1.0'
59+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:5.0.0'
6060
}
6161
```
6262

docs/zh/delegate.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
```groovy
1010
dependencies {
11-
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:4.1.0'
11+
implementation 'com.github.DylanCaiCoding.LoadingStateView:loadingstateview-ktx:5.0.0'
1212
}
1313
```
1414

loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/LoadingState.kt

+6-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.annotation.StringRes
2222
import androidx.fragment.app.Fragment
2323

2424
interface LoadingState : Decorative, OnReloadListener {
25+
val loadingStateViewType: Any?
2526

2627
@Deprecated("Use Activity.decorateContentView(this) instead", ReplaceWith("decorateContentView(decorative)"))
2728
fun Activity.decorateContentView(listener: OnReloadListener, decorative: Decorative) = decorateContentView(decorative)
@@ -51,15 +52,15 @@ interface LoadingState : Decorative, OnReloadListener {
5152

5253
fun Fragment.setDecorView(delegate: LoadingStateView.DecorViewDelegate)
5354

54-
fun showLoadingView(animation: LoadingStateView.Animation? = null)
55+
fun showLoadingView(animatable: LoadingStateView.Animatable? = LoadingStateView.defaultAnimatable)
5556

56-
fun showContentView(animation: LoadingStateView.Animation? = null)
57+
fun showContentView(animatable: LoadingStateView.Animatable? = LoadingStateView.defaultAnimatable)
5758

58-
fun showErrorView(animation: LoadingStateView.Animation? = null)
59+
fun showErrorView(animatable: LoadingStateView.Animatable? = LoadingStateView.defaultAnimatable)
5960

60-
fun showEmptyView(animation: LoadingStateView.Animation? = null)
61+
fun showEmptyView(animatable: LoadingStateView.Animatable? = LoadingStateView.defaultAnimatable)
6162

62-
fun showCustomView(viewType: Any)
63+
fun showCustomView(viewType: Any, animatable: LoadingStateView.Animatable? = LoadingStateView.defaultAnimatable)
6364

6465
fun updateToolbar(block: ToolbarConfig.() -> Unit)
6566

loadingstateview-ktx/src/main/java/com/dylanc/loadingstateview/LoadingStateDelegate.kt

+14-10
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import androidx.fragment.app.Fragment
2525
class LoadingStateDelegate : LoadingState {
2626
private var loadingStateView: LoadingStateView? = null
2727

28+
override val loadingStateViewType: Any?
29+
get() = loadingStateView?.currentViewType
30+
2831
override fun Activity.decorateContentView(decorative: Decorative) {
2932
findViewById<ViewGroup>(android.R.id.content).getChildAt(0).decorate(decorative)
3033
}
@@ -34,6 +37,7 @@ class LoadingStateDelegate : LoadingState {
3437
!decorative.isDecorated -> this
3538
decorative.contentView == null ->
3639
LoadingStateView(this, decorative).also { loadingStateView = it }.decorView
40+
3741
else -> {
3842
loadingStateView = LoadingStateView(decorative.contentView!!, decorative)
3943
this
@@ -76,24 +80,24 @@ class LoadingStateDelegate : LoadingState {
7680
loadingStateView?.addChildDecorView(delegate)
7781
}
7882

79-
override fun showLoadingView(animation: LoadingStateView.Animation?) {
80-
loadingStateView?.showLoadingView(animation)
83+
override fun showLoadingView(animatable: LoadingStateView.Animatable?) {
84+
loadingStateView?.showLoadingView(animatable)
8185
}
8286

83-
override fun showContentView(animation: LoadingStateView.Animation?) {
84-
loadingStateView?.showContentView(animation)
87+
override fun showContentView(animatable: LoadingStateView.Animatable?) {
88+
loadingStateView?.showContentView(animatable)
8589
}
8690

87-
override fun showErrorView(animation: LoadingStateView.Animation?) {
88-
loadingStateView?.showErrorView(animation)
91+
override fun showErrorView(animatable: LoadingStateView.Animatable?) {
92+
loadingStateView?.showErrorView(animatable)
8993
}
9094

91-
override fun showEmptyView(animation: LoadingStateView.Animation?) {
92-
loadingStateView?.showEmptyView(animation)
95+
override fun showEmptyView(animatable: LoadingStateView.Animatable?) {
96+
loadingStateView?.showEmptyView(animatable)
9397
}
9498

95-
override fun showCustomView(viewType: Any) {
96-
loadingStateView?.showView(viewType)
99+
override fun showCustomView(viewType: Any, animatable: LoadingStateView.Animatable?) {
100+
loadingStateView?.showView(viewType, animatable)
97101
}
98102

99103
override fun updateToolbar(block: ToolbarConfig.() -> Unit) {

loadingstateview/src/main/java/com/dylanc/loadingstateview/LoadingStateView.kt

+31-25
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class LoadingStateView @JvmOverloads constructor(
3939
private val parent: ViewGroup?
4040
private var currentView: View? = null
4141
private var viewDelegates: HashMap<Any, ViewDelegate> = HashMap()
42-
private val viewCashes: HashMap<Any, View> = HashMap()
42+
private val viewCaches: HashMap<Any, View> = HashMap()
4343

4444
/**
4545
* Constructs a LoadingStateView with an activity and listener.
@@ -111,6 +111,7 @@ class LoadingStateView @JvmOverloads constructor(
111111
onCreateDecorView(contentView.context, LayoutInflater.from(contentView.context)).also { decorView ->
112112
contentView.layoutParams?.let {
113113
decorView.layoutParams = if (it is ConstraintLayout.LayoutParams) ConstraintLayout.LayoutParams(it) else it
114+
(it as? ViewGroup.MarginLayoutParams)?.setMargins(0, 0, 0, 0)
114115
}
115116
}
116117

@@ -122,39 +123,41 @@ class LoadingStateView @JvmOverloads constructor(
122123
fun register(vararg delegates: ViewDelegate) = delegates.forEach { viewDelegates[it.viewType] = it }
123124

124125
@JvmOverloads
125-
fun showLoadingView(animation: Animation? = null) = showView(ViewType.LOADING, animation)
126+
fun showLoadingView(animatable: Animatable? = defaultAnimatable) = showView(ViewType.LOADING, animatable)
126127

127128
@JvmOverloads
128-
fun showContentView(animation: Animation? = null) = showView(ViewType.CONTENT, animation)
129+
fun showContentView(animatable: Animatable? = defaultAnimatable) = showView(ViewType.CONTENT, animatable)
129130

130131
@JvmOverloads
131-
fun showErrorView(animation: Animation? = null) = showView(ViewType.ERROR, animation)
132+
fun showErrorView(animatable: Animatable? = defaultAnimatable) = showView(ViewType.ERROR, animatable)
132133

133134
@JvmOverloads
134-
fun showEmptyView(animation: Animation? = null) = showView(ViewType.EMPTY, animation)
135+
fun showEmptyView(animatable: Animatable? = defaultAnimatable) = showView(ViewType.EMPTY, animatable)
135136

136137
/**
137138
* Shows the view by view type
138139
*
139140
* @param viewType the view type of view delegate
140141
*/
141142
@JvmOverloads
142-
fun showView(viewType: Any, animation: Animation? = null) {
143+
fun showView(viewType: Any, animatable: Animatable? = defaultAnimatable) {
143144
val currentView = currentView
144145
if (currentView == null) {
145146
addView(viewType)
146147
} else {
147-
if (viewCashes[viewType] == null) addView(viewType)
148+
if (viewCaches[viewType] == null) addView(viewType)
148149
if (viewType != currentViewType) {
149-
val view = getView(viewType)
150-
view.visibility = View.VISIBLE
151-
if (animation != null) {
152-
animation.onStartHideAnimation(currentView, currentViewType)
153-
animation.onStartShowAnimation(view, getViewDelegate<ViewDelegate>(viewType)!!.viewType)
150+
val nextView = getOrCreateView(viewType)
151+
nextView.visibility = View.VISIBLE
152+
val nextViewDelegate = getViewDelegate<ViewDelegate>(viewType)
153+
nextViewDelegate?.onViewAttached(nextView)
154+
getViewDelegate<ViewDelegate>(currentViewType)?.onViewDetached(nextView)
155+
if (animatable != null && nextViewDelegate != null) {
156+
animatable.toggleViewsAnimation(nextView, currentView, viewType, currentViewType)
154157
} else {
155158
currentView.visibility = View.GONE
156159
}
157-
this.currentView = view
160+
this.currentView = nextView
158161
}
159162
}
160163
currentViewType = viewType
@@ -167,7 +170,7 @@ class LoadingStateView @JvmOverloads constructor(
167170
fun <T : ViewDelegate> getViewDelegate(viewType: Any) = viewDelegates[viewType] as? T
168171

169172
private fun addView(viewType: Any) {
170-
val view = getView(viewType)
173+
val view = getOrCreateView(viewType)
171174
(view.parent as? ViewGroup)?.removeView(view)
172175
if (parent is ConstraintLayout && viewType == ViewType.CONTENT) {
173176
val params = view.layoutParams
@@ -179,24 +182,25 @@ class LoadingStateView @JvmOverloads constructor(
179182
currentView = view
180183
}
181184

182-
private fun getView(viewType: Any): View {
183-
if (viewCashes[viewType] == null) {
185+
private fun getOrCreateView(viewType: Any): View {
186+
if (viewCaches[viewType] == null) {
184187
val viewDelegate = requireNotNull(getViewDelegate(viewType)) { "Please register view delegate for $viewType type." }
185188
val view = viewDelegate.onCreateView(LayoutInflater.from(contentParent.context), contentParent)
186189
viewDelegate.onReloadListener = onReloadListener
187-
viewCashes[viewType] = view
190+
viewCaches[viewType] = view
188191
}
189-
return viewCashes[viewType]!!
192+
return viewCaches[viewType]!!
190193
}
191194

192195
abstract class ViewDelegate(val viewType: Any) {
196+
abstract fun onCreateView(inflater: LayoutInflater, parent: ViewGroup): View
197+
open fun onViewAttached(view: View) = Unit
198+
open fun onViewDetached(view: View) = Unit
193199
var onReloadListener: OnReloadListener? = null
194200
internal set
195-
196-
abstract fun onCreateView(inflater: LayoutInflater, parent: ViewGroup): View
197201
}
198202

199-
private inner class ContentViewDelegate : LoadingStateView.ViewDelegate(ViewType.CONTENT) {
203+
private inner class ContentViewDelegate : ViewDelegate(ViewType.CONTENT) {
200204
override fun onCreateView(inflater: LayoutInflater, parent: ViewGroup) = contentView
201205
}
202206

@@ -210,7 +214,7 @@ class LoadingStateView @JvmOverloads constructor(
210214

211215
constructor(delegates: Array<out ViewDelegate>) : this(delegates.map {
212216
register(it)
213-
getView(it.viewType)
217+
getOrCreateView(it.viewType)
214218
})
215219

216220
override fun onCreateDecorView(context: Context, inflater: LayoutInflater) =
@@ -233,14 +237,16 @@ class LoadingStateView @JvmOverloads constructor(
233237
fun T.invoke()
234238
}
235239

236-
interface Animation {
237-
fun onStartShowAnimation(view: View, viewType: Any)
238-
fun onStartHideAnimation(view: View, viewType: Any)
240+
interface Animatable {
241+
fun toggleViewsAnimation(showView: View, hideView: View, showViewType: Any, hideViewType: Any)
239242
}
240243

241244
companion object {
242245
private var poolInitializer: Callback<PoolInitializer>? = null
243246

247+
@JvmStatic
248+
var defaultAnimatable: Animatable? = null
249+
244250
@JvmStatic
245251
fun setViewDelegatePool(poolInitializer: Callback<PoolInitializer>) {
246252
this.poolInitializer = poolInitializer

sample-java/src/main/java/com/dylanc/loadingstateview/sample/java/App.java

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import android.app.Application;
2020

2121
import com.dylanc.loadingstateview.LoadingStateView;
22+
import com.dylanc.loadingstateview.sample.java.animation.FadeAnimatable;
2223
import com.dylanc.loadingstateview.sample.java.delegate.EmptyViewDelegate;
2324
import com.dylanc.loadingstateview.sample.java.delegate.ErrorViewDelegate;
2425
import com.dylanc.loadingstateview.sample.java.delegate.LoadingViewDelegate;
@@ -32,5 +33,6 @@ public void onCreate() {
3233
super.onCreate();
3334
LoadingStateView.setViewDelegatePool(pool ->
3435
pool.register(new LoadingViewDelegate(), new ErrorViewDelegate(), new EmptyViewDelegate()));
36+
LoadingStateView.setDefaultAnimatable(new FadeAnimatable());
3537
}
3638
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.dylanc.loadingstateview.sample.java.animation;
2+
3+
import android.view.View;
4+
5+
import androidx.annotation.NonNull;
6+
7+
import com.dylanc.loadingstateview.LoadingStateView;
8+
import com.dylanc.loadingstateview.ViewType;
9+
10+
import org.jetbrains.annotations.NotNull;
11+
12+
/**
13+
* @author Dylan Cai
14+
*/
15+
public class FadeAnimatable implements LoadingStateView.Animatable {
16+
17+
private static final long DEFAULT_DURATION = 500;
18+
private final long duration;
19+
20+
public FadeAnimatable() {
21+
this(DEFAULT_DURATION);
22+
}
23+
24+
public FadeAnimatable(long duration) {
25+
this.duration = duration;
26+
}
27+
28+
@Override
29+
public void toggleViewsAnimation(@NonNull View showView, @NonNull View hideView, @NonNull Object showViewType, @NonNull Object hideViewType) {
30+
showView.setAlpha(0);
31+
showView.setVisibility(View.VISIBLE);
32+
showView.animate().alpha(1).setDuration(duration);
33+
34+
if (showViewType == ViewType.LOADING && hideViewType == ViewType.CONTENT) {
35+
hideView.setVisibility(View.GONE);
36+
} else {
37+
hideView.animate().alpha(0).setDuration(duration).withEndAction(() -> {
38+
hideView.setAlpha(1);
39+
hideView.setVisibility(View.GONE);
40+
});
41+
}
42+
}
43+
}

sample-java/src/main/java/com/dylanc/loadingstateview/sample/java/animation/FadeAnimation.java

-39
This file was deleted.

0 commit comments

Comments
 (0)