1
+ package com .hannesdorfmann .mosby3 .mvp .lce ;
2
+
3
+ import android .os .Bundle ;
4
+ import android .support .annotation .CallSuper ;
5
+ import android .support .annotation .NonNull ;
6
+ import android .support .annotation .Nullable ;
7
+ import android .view .LayoutInflater ;
8
+ import android .view .View ;
9
+ import android .view .ViewGroup ;
10
+ import android .widget .TextView ;
11
+ import android .widget .Toast ;
12
+ import com .hannesdorfmann .mosby3 .mvp .MvpDialogFragment ;
13
+ import com .hannesdorfmann .mosby3 .mvp .MvpPresenter ;
14
+
15
+ /**
16
+ * A {@link MvpDialogFragment} that implements {@link MvpLceView} which gives you 3 options:
17
+ * <ul>
18
+ * <li>Display a loading view: A view with <b>R.id.loadingView</b> must be specified in your
19
+ * inflated xml layout</li>
20
+ * <li>Display a error view: A <b>TextView</b> with <b>R.id.errorView</b> must be declared in your
21
+ * inflated xml layout</li>
22
+ * <li>Display content view: A view with <b>R.id.contentView</b> must be specified in your
23
+ * inflated
24
+ * xml layout</li>
25
+ * </ul>
26
+ *
27
+ * @param <CV> The type of the content view with the id = R.id.contentView. Can be any kind of
28
+ * android view widget like ListView, RecyclerView, ScrollView or a simple layout like Framelayout
29
+ * etc. (everything that extends from android.view.View)
30
+ * @param <M> The underlying data model that will be displayed with this view
31
+ * @param <V> The View interface that must be implemented by this view. You can use {@link
32
+ * MvpLceView}, but if you want to add more methods you have to provide your own view interface
33
+ * that
34
+ * extends from {@link MvpLceView}
35
+ * @param <P> The type of the Presenter. Must extend from {@link MvpPresenter}
36
+ * @author Hannes Dorfmann
37
+ * @since 3.1.1
38
+ */
39
+ public abstract class MvpLceDialogFragment <CV extends View , M , V extends MvpLceView <M >, P extends MvpPresenter <V >>
40
+ extends MvpDialogFragment <V , P > implements MvpLceView <M > {
41
+
42
+ protected View loadingView ;
43
+ protected CV contentView ;
44
+ protected TextView errorView ;
45
+
46
+ @ CallSuper @ Override public void onViewCreated (View view , @ Nullable Bundle savedInstanceState ) {
47
+ super .onViewCreated (view , savedInstanceState );
48
+
49
+ loadingView = createLoadingView (view );
50
+ contentView = createContentView (view );
51
+ errorView = createErrorView (view );
52
+
53
+ if (loadingView == null ) {
54
+ throw new NullPointerException (
55
+ "Loading view is null! Have you specified a loading view in your layout xml file?"
56
+ + " You have to give your loading View the id R.id.loadingView" );
57
+ }
58
+
59
+ if (contentView == null ) {
60
+ throw new NullPointerException (
61
+ "Content view is null! Have you specified a content view in your layout xml file?"
62
+ + " You have to give your content View the id R.id.contentView" );
63
+ }
64
+
65
+ if (errorView == null ) {
66
+ throw new NullPointerException (
67
+ "Error view is null! Have you specified a content view in your layout xml file?"
68
+ + " You have to give your error View the id R.id.errorView" );
69
+ }
70
+
71
+ errorView .setOnClickListener (new View .OnClickListener () {
72
+ @ Override public void onClick (View v ) {
73
+ onErrorViewClicked ();
74
+ }
75
+ });
76
+ }
77
+
78
+ /**
79
+ * Create the loading view. Default is {@code findViewById(R.id.loadingView)}
80
+ *
81
+ * @param view The main view returned from {@link #onCreateView(LayoutInflater, ViewGroup, * Bundle)}
82
+ * @return the loading view
83
+ */
84
+ @ NonNull protected View createLoadingView (View view ) {
85
+ return view .findViewById (R .id .loadingView );
86
+ }
87
+
88
+ /**
89
+ * Create the content view. Default is {@code findViewById(R.id.contentView)}
90
+ *
91
+ * @param view The main view returned from {@link #onCreateView(LayoutInflater, ViewGroup, *
92
+ * Bundle)}
93
+ * @return the content view
94
+ */
95
+ @ NonNull protected CV createContentView (View view ) {
96
+ return (CV ) view .findViewById (R .id .contentView );
97
+ }
98
+
99
+ /**
100
+ * Create the error view. Default is {@code findViewById(R.id.errorView)}
101
+ *
102
+ * @param view The main view returned from {@link #onCreateView(LayoutInflater, ViewGroup, *
103
+ * Bundle)}
104
+ * @return the error view
105
+ */
106
+ @ NonNull protected TextView createErrorView (View view ) {
107
+ return (TextView ) view .findViewById (R .id .errorView );
108
+ }
109
+
110
+ @ Override public void showLoading (boolean pullToRefresh ) {
111
+
112
+ if (!pullToRefresh ) {
113
+ animateLoadingViewIn ();
114
+ }
115
+
116
+ // otherwise the pull to refresh widget will already display a loading animation
117
+ }
118
+
119
+ /**
120
+ * Override this method if you want to provide your own animation for showing the loading view
121
+ */
122
+ protected void animateLoadingViewIn () {
123
+ LceAnimator .showLoading (loadingView , contentView , errorView );
124
+ }
125
+
126
+ @ Override public void showContent () {
127
+ animateContentViewIn ();
128
+ }
129
+
130
+ /**
131
+ * Called to animate from loading view to content view
132
+ */
133
+ protected void animateContentViewIn () {
134
+ LceAnimator .showContent (loadingView , contentView , errorView );
135
+ }
136
+
137
+ /**
138
+ * Get the error message for a certain Exception that will be shown on {@link
139
+ * #showError(Throwable, boolean)}
140
+ */
141
+ protected abstract String getErrorMessage (Throwable e , boolean pullToRefresh );
142
+
143
+ /**
144
+ * The default behaviour is to display a toast message as light error (i.e. pull-to-refresh
145
+ * error).
146
+ * Override this method if you want to display the light error in another way (like crouton).
147
+ */
148
+ protected void showLightError (String msg ) {
149
+ if (getActivity () != null ) {
150
+ Toast .makeText (getActivity (), msg , Toast .LENGTH_SHORT ).show ();
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Called if the error view has been clicked. To disable clicking on the errorView use
156
+ * <code>errorView.setClickable(false)</code>
157
+ */
158
+ protected void onErrorViewClicked () {
159
+ loadData (false );
160
+ }
161
+
162
+ @ Override
163
+ public void showError (Throwable e , boolean pullToRefresh ) {
164
+
165
+ String errorMsg = getErrorMessage (e , pullToRefresh );
166
+
167
+ if (pullToRefresh ) {
168
+ showLightError (errorMsg );
169
+ } else {
170
+ errorView .setText (errorMsg );
171
+ animateErrorViewIn ();
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Animates the error view in (instead of displaying content view / loading view)
177
+ */
178
+ protected void animateErrorViewIn () {
179
+ LceAnimator .showErrorView (loadingView , contentView , errorView );
180
+ }
181
+
182
+ @ Override
183
+ public void onDestroyView () {
184
+ super .onDestroyView ();
185
+ loadingView = null ;
186
+ contentView = null ;
187
+ errorView .setOnClickListener (null );
188
+ errorView = null ;
189
+ }
190
+
191
+ }
0 commit comments