Skip to content

Commit f9a63b0

Browse files
refactor: replace Animation interface with Animatable interface
- Replaced `Animation` interface with `Animatable` interface - Changed `onStartShowAnimation` and `onStartHideAnimation` methods to `toggleViewsAnimation` method Closes #34
1 parent 06ee57d commit f9a63b0

File tree

11 files changed

+132
-87
lines changed

11 files changed

+132
-87
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ interface LoadingState : Decorative, OnReloadListener {
5252

5353
fun Fragment.setDecorView(delegate: LoadingStateView.DecorViewDelegate)
5454

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

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

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

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

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

6565
fun updateToolbar(block: ToolbarConfig.() -> Unit)
6666

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

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class LoadingStateDelegate : LoadingState {
3737
!decorative.isDecorated -> this
3838
decorative.contentView == null ->
3939
LoadingStateView(this, decorative).also { loadingStateView = it }.decorView
40+
4041
else -> {
4142
loadingStateView = LoadingStateView(decorative.contentView!!, decorative)
4243
this
@@ -79,24 +80,24 @@ class LoadingStateDelegate : LoadingState {
7980
loadingStateView?.addChildDecorView(delegate)
8081
}
8182

82-
override fun showLoadingView(animation: LoadingStateView.Animation?) {
83-
loadingStateView?.showLoadingView(animation)
83+
override fun showLoadingView(animatable: LoadingStateView.Animatable?) {
84+
loadingStateView?.showLoadingView(animatable)
8485
}
8586

86-
override fun showContentView(animation: LoadingStateView.Animation?) {
87-
loadingStateView?.showContentView(animation)
87+
override fun showContentView(animatable: LoadingStateView.Animatable?) {
88+
loadingStateView?.showContentView(animatable)
8889
}
8990

90-
override fun showErrorView(animation: LoadingStateView.Animation?) {
91-
loadingStateView?.showErrorView(animation)
91+
override fun showErrorView(animatable: LoadingStateView.Animatable?) {
92+
loadingStateView?.showErrorView(animatable)
9293
}
9394

94-
override fun showEmptyView(animation: LoadingStateView.Animation?) {
95-
loadingStateView?.showEmptyView(animation)
95+
override fun showEmptyView(animatable: LoadingStateView.Animatable?) {
96+
loadingStateView?.showEmptyView(animatable)
9697
}
9798

98-
override fun showCustomView(viewType: Any) {
99-
loadingStateView?.showView(viewType)
99+
override fun showCustomView(viewType: Any, animatable: LoadingStateView.Animatable?) {
100+
loadingStateView?.showView(viewType, animatable)
100101
}
101102

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

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

Lines changed: 26 additions & 24 deletions
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.
@@ -123,41 +123,41 @@ class LoadingStateView @JvmOverloads constructor(
123123
fun register(vararg delegates: ViewDelegate) = delegates.forEach { viewDelegates[it.viewType] = it }
124124

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

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

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

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

137137
/**
138138
* Shows the view by view type
139139
*
140140
* @param viewType the view type of view delegate
141141
*/
142142
@JvmOverloads
143-
fun showView(viewType: Any, animation: Animation? = null) {
143+
fun showView(viewType: Any, animatable: Animatable? = defaultAnimatable) {
144144
val currentView = currentView
145145
if (currentView == null) {
146146
addView(viewType)
147147
} else {
148-
if (viewCashes[viewType] == null) addView(viewType)
148+
if (viewCaches[viewType] == null) addView(viewType)
149149
if (viewType != currentViewType) {
150-
val view = getView(viewType)
151-
view.visibility = View.VISIBLE
152-
getViewDelegate<ViewDelegate>(viewType)?.onViewAttached(view)
153-
if (animation != null) {
154-
animation.onStartHideAnimation(currentView, currentViewType)
155-
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)
156157
} else {
157158
currentView.visibility = View.GONE
158159
}
159-
getViewDelegate<ViewDelegate>(currentViewType)?.onViewDetached(view)
160-
this.currentView = view
160+
this.currentView = nextView
161161
}
162162
}
163163
currentViewType = viewType
@@ -170,7 +170,7 @@ class LoadingStateView @JvmOverloads constructor(
170170
fun <T : ViewDelegate> getViewDelegate(viewType: Any) = viewDelegates[viewType] as? T
171171

172172
private fun addView(viewType: Any) {
173-
val view = getView(viewType)
173+
val view = getOrCreateView(viewType)
174174
(view.parent as? ViewGroup)?.removeView(view)
175175
if (parent is ConstraintLayout && viewType == ViewType.CONTENT) {
176176
val params = view.layoutParams
@@ -182,14 +182,14 @@ class LoadingStateView @JvmOverloads constructor(
182182
currentView = view
183183
}
184184

185-
private fun getView(viewType: Any): View {
186-
if (viewCashes[viewType] == null) {
185+
private fun getOrCreateView(viewType: Any): View {
186+
if (viewCaches[viewType] == null) {
187187
val viewDelegate = requireNotNull(getViewDelegate(viewType)) { "Please register view delegate for $viewType type." }
188188
val view = viewDelegate.onCreateView(LayoutInflater.from(contentParent.context), contentParent)
189189
viewDelegate.onReloadListener = onReloadListener
190-
viewCashes[viewType] = view
190+
viewCaches[viewType] = view
191191
}
192-
return viewCashes[viewType]!!
192+
return viewCaches[viewType]!!
193193
}
194194

195195
abstract class ViewDelegate(val viewType: Any) {
@@ -214,7 +214,7 @@ class LoadingStateView @JvmOverloads constructor(
214214

215215
constructor(delegates: Array<out ViewDelegate>) : this(delegates.map {
216216
register(it)
217-
getView(it.viewType)
217+
getOrCreateView(it.viewType)
218218
})
219219

220220
override fun onCreateDecorView(context: Context, inflater: LayoutInflater) =
@@ -237,14 +237,16 @@ class LoadingStateView @JvmOverloads constructor(
237237
fun T.invoke()
238238
}
239239

240-
interface Animation {
241-
fun onStartShowAnimation(view: View, viewType: Any)
242-
fun onStartHideAnimation(view: View, viewType: Any)
240+
interface Animatable {
241+
fun toggleViewsAnimation(showView: View, hideView: View, showViewType: Any, hideViewType: Any)
243242
}
244243

245244
companion object {
246245
private var poolInitializer: Callback<PoolInitializer>? = null
247246

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

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

Lines changed: 2 additions & 0 deletions
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
}
Lines changed: 43 additions & 0 deletions
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

Lines changed: 0 additions & 39 deletions
This file was deleted.

sample-java/src/main/java/com/dylanc/loadingstateview/sample/java/ui/ActErrorActivity.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.dylanc.loadingstateview.OnReloadListener;
2626
import com.dylanc.loadingstateview.sample.java.R;
2727
import com.dylanc.loadingstateview.sample.java.delegate.NavIconType;
28-
import com.dylanc.loadingstateview.sample.java.animation.FadeAnimation;
2928
import com.dylanc.loadingstateview.sample.java.utils.HttpUtils;
3029
import com.dylanc.loadingstateview.sample.java.utils.ToolbarUtils;
3130

@@ -50,28 +49,28 @@ private void loadData() {
5049
HttpUtils.requestFailure(new HttpUtils.Callback() {
5150
@Override
5251
public void onSuccess() {
53-
loadingStateView.showContentView(new FadeAnimation());
52+
loadingStateView.showContentView();
5453
}
5554

5655
@Override
5756
public void onFailure() {
58-
loadingStateView.showErrorView(new FadeAnimation());
57+
loadingStateView.showErrorView();
5958
}
6059
});
6160
}
6261

6362
@Override
6463
public void onReload() {
65-
loadingStateView.showLoadingView(new FadeAnimation());
64+
loadingStateView.showLoadingView();
6665
HttpUtils.requestSuccess(new HttpUtils.Callback() {
6766
@Override
6867
public void onSuccess() {
69-
loadingStateView.showContentView(new FadeAnimation());
68+
loadingStateView.showContentView();
7069
}
7170

7271
@Override
7372
public void onFailure() {
74-
loadingStateView.showErrorView(new FadeAnimation());
73+
loadingStateView.showErrorView();
7574
}
7675
});
7776
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.dylanc.loadingstateview.sample.kotlin.delegate.ErrorViewDelegate
66
import com.dylanc.loadingstateview.sample.kotlin.delegate.LoadingViewDelegate
77
import com.dylanc.loadingstateview.sample.kotlin.delegate.ToolbarViewDelegate
88
import com.dylanc.loadingstateview.sample.kotlin.delegate.EmptyViewDelegate
9+
import com.dylanc.loadingstateview.sample.kotlin.delegate.FadeAnimatable
910

1011
class App : Application() {
1112

@@ -14,5 +15,6 @@ class App : Application() {
1415
LoadingStateView.setViewDelegatePool {
1516
register(ToolbarViewDelegate(), LoadingViewDelegate(), ErrorViewDelegate(), EmptyViewDelegate())
1617
}
18+
LoadingStateView.defaultAnimatable = FadeAnimatable()
1719
}
1820
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.dylanc.loadingstateview.sample.kotlin.delegate
2+
3+
import android.view.View
4+
import com.dylanc.loadingstateview.LoadingStateView
5+
import com.dylanc.loadingstateview.ViewType
6+
7+
/**
8+
* @author Dylan Cai
9+
*/
10+
class FadeAnimatable @JvmOverloads constructor(
11+
private val duration: Long = DEFAULT_DURATION
12+
) : LoadingStateView.Animatable {
13+
override fun toggleViewsAnimation(showView: View, hideView: View, showViewType: Any, hideViewType: Any) {
14+
showView.alpha = 0f
15+
showView.visibility = View.VISIBLE
16+
showView.animate().alpha(1f).setDuration(duration)
17+
18+
if (showViewType === ViewType.LOADING && hideViewType === ViewType.CONTENT) {
19+
hideView.visibility = View.GONE
20+
} else {
21+
hideView.animate().alpha(0f).setDuration(duration).withEndAction {
22+
hideView.alpha = 1f
23+
hideView.visibility = View.GONE
24+
}
25+
}
26+
}
27+
28+
companion object {
29+
private const val DEFAULT_DURATION: Long = 600
30+
}
31+
}

sample-kotlin/src/main/java/com/dylanc/loadingstateview/sample/kotlin/ui/MainActivity.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ class MainActivity : BaseBindingActivity<ActivityMainBinding>() {
3333
rightTextColor = Color.BLUE
3434
rightText("Edit") { onEdit() }
3535
}
36-
showErrorView()
36+
showLoadingView()
37+
Handler(Looper.getMainLooper()).postDelayed({
38+
showErrorView()
39+
}, 2000)
3740
}
3841

3942
private fun onEdit() {

0 commit comments

Comments
 (0)