forked from openMF/android-client
/
ClientListFragment.java
executable file
·426 lines (373 loc) · 14.9 KB
/
ClientListFragment.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/*
* This project is licensed under the open source MPL V2.
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.mifosxdroid.online.clientlist;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.mifos.mifosxdroid.R;
import com.mifos.mifosxdroid.adapters.ClientNameListAdapter;
import com.mifos.mifosxdroid.core.EndlessRecyclerViewScrollListener;
import com.mifos.mifosxdroid.core.MifosBaseActivity;
import com.mifos.mifosxdroid.core.MifosBaseFragment;
import com.mifos.mifosxdroid.core.RecyclerItemClickListener;
import com.mifos.mifosxdroid.core.RecyclerItemClickListener.OnItemClickListener;
import com.mifos.mifosxdroid.core.util.Toaster;
import com.mifos.mifosxdroid.dialogfragments.syncclientsdialog.SyncClientsDialogFragment;
import com.mifos.mifosxdroid.online.ClientActivity;
import com.mifos.mifosxdroid.online.createnewclient.CreateNewClientFragment;
import com.mifos.objects.client.Client;
import com.mifos.utils.Constants;
import com.mifos.utils.FragmentConstants;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Created by ishankhanna on 09/02/14.
* <p>
* This class loading client, Here is two way to load the clients. First one to load clients
* from Rest API
* <p>
* </>demo.openmf.org/fineract-provider/api/v1/clients?paged=true&offset=offset_value&limit
* =limit_value</>
* <p>
* Offset : From Where index, client will be fetch.
* limit : Total number of client, need to fetch
* <p>
* and showing in the ClientList.
* <p>
* and Second one is showing Group Clients. Here Group load the ClientList and send the
* Client to ClientListFragment newInstance(List<Client> clientList,
* boolean isParentFragment) {...}
* and unregister the ScrollListener and SwipeLayout.
*/
public class ClientListFragment extends MifosBaseFragment
implements OnItemClickListener, ClientListMvpView, SwipeRefreshLayout.OnRefreshListener {
public static final String LOG_TAG = ClientListFragment.class.getSimpleName();
@BindView(R.id.rv_clients)
RecyclerView rv_clients;
@BindView(R.id.swipe_container)
SwipeRefreshLayout swipeRefreshLayout;
@BindView(R.id.noClientText)
TextView mNoClientText;
@BindView(R.id.rl_error)
RelativeLayout rlError;
@BindView(R.id.noClientIcon)
ImageView mNoClientIcon;
@Inject
ClientNameListAdapter mClientNameListAdapter;
@Inject
ClientListPresenter mClientListPresenter;
private View rootView;
private List<Client> clientList;
private List<Client> selectedClients;
private ActionModeCallback actionModeCallback;
private ActionMode actionMode;
private Boolean isParentFragment = false;
private LinearLayoutManager mLayoutManager;
@Override
public void onItemClick(View childView, int position) {
if (actionMode != null) {
toggleSelection(position);
} else {
Intent clientActivityIntent = new Intent(getActivity(), ClientActivity.class);
clientActivityIntent.putExtra(Constants.CLIENT_ID, clientList.get(position).getId());
startActivity(clientActivityIntent);
}
}
@Override
public void onItemLongPress(View childView, int position) {
if (actionMode == null) {
actionMode = ((MifosBaseActivity) getActivity()).startSupportActionMode
(actionModeCallback);
}
toggleSelection(position);
}
/**
* This method will be called, whenever ClientListFragment will not have Parent Fragment.
* So, Presenter make the call to Rest API and fetch the Client List and show in UI
*
* @return ClientListFragment
*/
public static ClientListFragment newInstance() {
Bundle arguments = new Bundle();
ClientListFragment clientListFragment = new ClientListFragment();
clientListFragment.setArguments(arguments);
return clientListFragment;
}
/**
* This Method will be called, whenever Parent (Fragment or Activity) will be true and Presenter
* do not need to make Rest API call to server. Parent (Fragment or Activity) already fetched
* the clients and for showing, they call ClientListFragment.
* <p>
* Example : Showing Group Clients.
*
* @param clientList List<Client>
* @param isParentFragment true
* @return ClientListFragment
*/
public static ClientListFragment newInstance(List<Client> clientList,
boolean isParentFragment) {
ClientListFragment clientListFragment = new ClientListFragment();
Bundle args = new Bundle();
if (isParentFragment && clientList != null) {
args.putParcelableArrayList(Constants.CLIENTS,
(ArrayList<? extends Parcelable>) clientList);
args.putBoolean(Constants.IS_A_PARENT_FRAGMENT, true);
clientListFragment.setArguments(args);
}
return clientListFragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((MifosBaseActivity) getActivity()).getActivityComponent().inject(this);
clientList = new ArrayList<>();
selectedClients = new ArrayList<>();
actionModeCallback = new ActionModeCallback();
if (getArguments() != null) {
clientList = getArguments().getParcelableArrayList(Constants.CLIENTS);
isParentFragment = getArguments()
.getBoolean(Constants.IS_A_PARENT_FRAGMENT);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_client, container, false);
setHasOptionsMenu(true);
setToolbarTitle(getResources().getString(R.string.clients));
ButterKnife.bind(this, rootView);
mClientListPresenter.attachView(this);
//setting all the UI content to the view
showUserInterface();
/**
* This is the LoadMore of the RecyclerView. It called When Last Element of RecyclerView
* is shown on the Screen.
*/
rv_clients.addOnScrollListener(new EndlessRecyclerViewScrollListener(mLayoutManager) {
@Override
public void onLoadMore(int page, int totalItemCount) {
mClientListPresenter.loadClients(true, totalItemCount);
}
});
/**
* First Check the Parent Fragment is true or false. If parent fragment is true then no
* need to fetch clientList from Rest API, just need to showing parent fragment ClientList
* and is Parent Fragment is false then Presenter make the call to Rest API and fetch the
* Client Lis to show. and Presenter make transaction to Database to load saved clients.
*/
if (isParentFragment) {
mClientListPresenter.showParentClients(clientList);
} else {
mClientListPresenter.loadClients(false, 0);
}
mClientListPresenter.loadDatabaseClients();
return rootView;
}
/**
* This method initializes the all Views.
*/
@Override
public void showUserInterface() {
mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mClientNameListAdapter.setContext(getActivity());
rv_clients.setLayoutManager(mLayoutManager);
rv_clients.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(), this));
rv_clients.setHasFixedSize(true);
rv_clients.setAdapter(mClientNameListAdapter);
swipeRefreshLayout.setColorSchemeColors(getActivity()
.getResources().getIntArray(R.array.swipeRefreshColors));
swipeRefreshLayout.setOnRefreshListener(this);
}
@OnClick(R.id.fab_create_client)
void onClickCreateNewClient() {
((MifosBaseActivity) getActivity()).replaceFragment(CreateNewClientFragment.newInstance(),
true, R.id.container);
}
/**
* This method will be called when user will swipe down to Refresh the ClientList then
* Presenter make the Fresh call to Rest API to load ClientList from offset = 0 and fetch the
* first 100 clients and update the client list.
*/
@Override
public void onRefresh() {
showUserInterface();
mClientListPresenter.loadClients(false, 0);
mClientListPresenter.loadDatabaseClients();
if (actionMode != null) actionMode.finish();
}
/**
* This Method unregister the RecyclerView OnScrollListener and SwipeRefreshLayout
* and NoClientIcon click event.
*/
@Override
public void unregisterSwipeAndScrollListener() {
rv_clients.clearOnScrollListeners();
swipeRefreshLayout.setEnabled(false);
mNoClientIcon.setEnabled(false);
}
/**
* This Method showing the Simple Taster Message to user.
*
* @param message String Message to show.
*/
@Override
public void showMessage(int message) {
Toaster.show(rootView, getStringMessage(message));
}
/**
* Onclick Send Fresh Request for Client list.
*/
@OnClick(R.id.noClientIcon)
public void reloadOnError() {
rlError.setVisibility(View.GONE);
rv_clients.setVisibility(View.VISIBLE);
mClientListPresenter.loadClients(false, 0);
mClientListPresenter.loadDatabaseClients();
}
/**
* Setting ClientList to the Adapter and updating the Adapter.
*/
@Override
public void showClientList(List<Client> clients) {
clientList = clients;
mClientNameListAdapter.setClients(clients);
mClientNameListAdapter.notifyDataSetChanged();
}
/**
* Updating Adapter Attached ClientList
*
* @param clients List<Client></>
*/
@Override
public void showLoadMoreClients(List<Client> clients) {
clientList.addAll(clients);
mClientNameListAdapter.notifyDataSetChanged();
}
/**
* Showing Fetched ClientList size is 0 and show there is no client to show.
*
* @param message String Message to show user.
*/
@Override
public void showEmptyClientList(int message) {
rv_clients.setVisibility(View.GONE);
rlError.setVisibility(View.VISIBLE);
mNoClientText.setText(getStringMessage(message));
}
/**
* This Method Will be called. When Presenter failed to First page of ClientList from Rest API.
* Then user look the Message that failed to fetch clientList.
*/
@Override
public void showError() {
rv_clients.setVisibility(View.GONE);
rlError.setVisibility(View.VISIBLE);
String errorMessage = getStringMessage(R.string.failed_to_load_client)
+ getStringMessage(R.string.new_line) + getStringMessage(R.string.click_to_refresh);
mNoClientText.setText(errorMessage);
}
/**
* show MifosBaseActivity ProgressBar, if mClientNameListAdapter.getItemCount() == 0
* otherwise show SwipeRefreshLayout.
*/
@Override
public void showProgressbar(boolean show) {
swipeRefreshLayout.setRefreshing(show);
if (show && mClientNameListAdapter.getItemCount() == 0) {
showMifosProgressBar();
swipeRefreshLayout.setRefreshing(false);
} else {
hideMifosProgressBar();
}
}
@Override
public void onDestroyView() {
super.onDestroyView();
hideMifosProgressBar();
mClientListPresenter.detachView();
//As the Fragment Detach Finish the ActionMode
if (actionMode != null) actionMode.finish();
}
/**
* Toggle the selection state of an item.
* <p>
* If the item was the last one in the selection and is unselected, the selection is stopped.
* Note that the selection must already be started (actionMode must not be null).
*
* @param position Position of the item to toggle the selection state
*/
private void toggleSelection(int position) {
mClientNameListAdapter.toggleSelection(position);
int count = mClientNameListAdapter.getSelectedItemCount();
if (count == 0) {
actionMode.finish();
} else {
actionMode.setTitle(String.valueOf(count));
actionMode.invalidate();
}
}
/**
* This ActionModeCallBack Class handling the User Event after the Selection of Clients. Like
* Click of Menu Sync Button and finish the ActionMode
*/
private class ActionModeCallback implements ActionMode.Callback {
@SuppressWarnings("unused")
private final String LOG_TAG = ActionModeCallback.class.getSimpleName();
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_sync, menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_sync:
selectedClients.clear();
for (Integer position : mClientNameListAdapter.getSelectedItems()) {
selectedClients.add(clientList.get(position));
}
SyncClientsDialogFragment syncClientsDialogFragment =
SyncClientsDialogFragment.newInstance(selectedClients);
FragmentTransaction fragmentTransaction = getActivity()
.getSupportFragmentManager().beginTransaction();
fragmentTransaction.addToBackStack(FragmentConstants.FRAG_CLIENT_SYNC);
syncClientsDialogFragment.setCancelable(false);
syncClientsDialogFragment.show(fragmentTransaction,
getResources().getString(R.string.sync_clients));
mode.finish();
return true;
default:
return false;
}
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mClientNameListAdapter.clearSelection();
actionMode = null;
}
}
}