1
1
package com .parse .ui .widget .sample ;
2
2
3
+ import android .database .DataSetObserver ;
3
4
import android .os .Bundle ;
4
5
import android .support .annotation .Nullable ;
5
6
import android .support .v7 .app .AppCompatActivity ;
6
- import android .util .Log ;
7
+ import android .view .LayoutInflater ;
8
+ import android .view .View ;
9
+ import android .view .ViewGroup ;
10
+ import android .widget .BaseAdapter ;
7
11
import android .widget .ListView ;
8
- import android .widget .Toast ;
12
+ import android .widget .ProgressBar ;
13
+ import android .widget .TextView ;
9
14
15
+ import com .parse .FindCallback ;
10
16
import com .parse .ParseException ;
11
17
import com .parse .ParseObject ;
12
18
import com .parse .ParseQuery ;
13
- import com .parse .ParseQueryAdapter ;
19
+ import com .parse .widget . util . ParseQueryPager ;
14
20
15
21
import java .util .List ;
16
22
23
+ import bolts .CancellationTokenSource ;
17
24
18
- public class ListActivity extends AppCompatActivity {
19
25
20
- private static final String TAG = "ListActivity" ;
26
+ public class ListActivity extends AppCompatActivity {
21
27
22
28
@ Override
23
29
protected void onCreate (@ Nullable Bundle savedInstanceState ) {
@@ -26,32 +32,205 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
26
32
27
33
ListView listView = (ListView ) findViewById (R .id .list );
28
34
29
- ParseQueryAdapter <ParseObject > adapter = new ParseQueryAdapter <>(this ,
30
- new ParseQueryAdapter .QueryFactory <ParseObject >() {
31
- @ Override
32
- public ParseQuery <ParseObject > create () {
33
- return ParseQuery .getQuery ("Contact" )
34
- .orderByAscending ("name" )
35
- .setCachePolicy (ParseQuery .CachePolicy .CACHE_THEN_NETWORK );
35
+ MyAdapter <ParseObject > adapter = new MyAdapter <>(createPager ());
36
+ listView .setAdapter (adapter );
37
+ }
38
+
39
+ private ParseQueryPager <ParseObject > createPager () {
40
+ ParseQuery <ParseObject > query = ParseQuery .getQuery ("TestObject" );
41
+ query .orderByAscending ("name" );
42
+ query .setCachePolicy (ParseQuery .CachePolicy .CACHE_THEN_NETWORK );
43
+ return new ParseQueryPager <>(query , 25 );
44
+ }
45
+
46
+ public static class MyAdapter <T extends ParseObject > extends BaseAdapter {
47
+
48
+ public static final int TYPE_ITEM = 0 ;
49
+ public static final int TYPE_NEXT = 1 ;
50
+
51
+ private static class ItemViewHolder extends ViewHolder {
52
+ TextView textView ;
53
+
54
+ public ItemViewHolder (View itemView ) {
55
+ super (itemView );
56
+ textView = (TextView ) itemView ;
57
+ }
58
+ }
59
+
60
+ private static class NextViewHolder extends ViewHolder {
61
+ TextView textView ;
62
+ ProgressBar progressBar ;
63
+
64
+ public NextViewHolder (View itemView ) {
65
+ super (itemView );
66
+ textView = (TextView ) itemView .findViewById (android .R .id .text1 );
67
+ progressBar = (ProgressBar ) itemView .findViewById (android .R .id .progress );
68
+ }
69
+
70
+ public void setLoading (boolean loading ) {
71
+ if (loading ) {
72
+ textView .setVisibility (View .INVISIBLE );
73
+ progressBar .setVisibility (View .VISIBLE );
74
+ progressBar .setIndeterminate (true );
75
+ } else {
76
+ textView .setVisibility (View .VISIBLE );
77
+ progressBar .setVisibility (View .INVISIBLE );
78
+ progressBar .setIndeterminate (false );
79
+ }
80
+ }
81
+ }
82
+
83
+ private final Object lock = new Object ();
84
+ private ParseQueryPager <T > pager ;
85
+ private CancellationTokenSource cts ;
86
+
87
+ public MyAdapter (ParseQueryPager <T > pager ) {
88
+ swap (pager );
89
+ }
90
+
91
+ public ParseQueryPager <T > getPager () {
92
+ synchronized (lock ) {
93
+ return pager ;
94
+ }
95
+ }
96
+
97
+ public void swap (ParseQueryPager <T > pager ) {
98
+ synchronized (lock ) {
99
+ if (cts != null ) {
100
+ cts .cancel ();
101
+ }
102
+ this .pager = pager ;
103
+ this .cts = new CancellationTokenSource ();
104
+ }
105
+ }
106
+
107
+ private void loadNextPage () {
108
+ final ParseQueryPager <T > pager ;
109
+ final CancellationTokenSource cts ;
110
+
111
+ synchronized (lock ) {
112
+ pager = this .pager ;
113
+ cts = this .cts ;
114
+ }
115
+
116
+ // Utilizing callbacks to support CACHE_THEN_NETWORK
117
+ pager .loadNextPage (new FindCallback <T >() {
118
+ @ Override
119
+ public void done (List <T > results , ParseException e ) {
120
+ if (results == null && e == null ) { // cancelled
121
+ return ;
122
+ }
123
+
124
+ if (e != null ) {
125
+ notifyDataSetChanged ();
126
+ return ;
36
127
}
37
- }, android .R .layout .simple_list_item_1 );
38
- adapter .setTextKey ("name" );
39
- adapter .addOnQueryLoadListener (new ParseQueryAdapter .OnQueryLoadListener <ParseObject >() {
40
- @ Override
41
- public void onLoading () {
42
- Log .d (TAG , "loading" );
43
- }
44
-
45
- @ Override
46
- public void onLoaded (List <ParseObject > objects , Exception e ) {
47
- Log .d (TAG , "loaded" );
48
- if (e != null
49
- && e instanceof ParseException
50
- && ((ParseException ) e ).getCode () != ParseException .CACHE_MISS ) {
51
- Toast .makeText (ListActivity .this , "Error: " + e .getMessage (), Toast .LENGTH_LONG ).show ();
128
+
129
+ notifyDataSetChanged ();
52
130
}
131
+ }, cts .getToken ());
132
+ notifyDataSetChanged ();
133
+ }
134
+
135
+ @ Override
136
+ public int getCount () {
137
+ ParseQueryPager <T > pager = getPager ();
138
+ return pager .getObjects ().size () + (pager .hasNextPage () ? 1 : 0 );
139
+ }
140
+
141
+ @ Override
142
+ public T getItem (int position ) {
143
+ List <T > objects = getPager ().getObjects ();
144
+ return position < objects .size () ? objects .get (position ) : null ;
145
+ }
146
+
147
+ @ Override
148
+ public long getItemId (int position ) {
149
+ return position ;
150
+ }
151
+
152
+ @ Override
153
+ public final View getView (int position , View convertView , ViewGroup parent ) {
154
+ ViewHolder holder ;
155
+ View view ;
156
+ if (convertView == null ) {
157
+ holder = onCreateViewHolder (parent , getItemViewType (position ));
158
+ view = holder .itemView ;
159
+ view .setTag (holder );
160
+ } else {
161
+ view = convertView ;
162
+ holder = (ViewHolder ) view .getTag ();
53
163
}
54
- });
55
- listView .setAdapter (adapter );
164
+ onBindViewHolder (holder , position );
165
+ return view ;
166
+ }
167
+
168
+ public ViewHolder onCreateViewHolder (ViewGroup parent , int viewType ) {
169
+ LayoutInflater inflater = LayoutInflater .from (parent .getContext ());
170
+ switch (viewType ) {
171
+ case TYPE_ITEM : {
172
+ View v = inflater .inflate (android .R .layout .simple_list_item_1 , parent , false );
173
+ return new ItemViewHolder (v );
174
+ }
175
+ case TYPE_NEXT : {
176
+ View v = inflater .inflate (R .layout .load_more_list_item , parent , false );
177
+ v .setOnClickListener (new View .OnClickListener () {
178
+ @ Override
179
+ public void onClick (View v ) {
180
+ if (!getPager ().isLoadingNextPage ()) {
181
+ loadNextPage ();
182
+ }
183
+ }
184
+ });
185
+ NextViewHolder vh = new NextViewHolder (v );
186
+ vh .textView .setText (R .string .load_more );
187
+ return vh ;
188
+ }
189
+ default :
190
+ throw new IllegalStateException ("Invalid view type: " + viewType );
191
+ }
192
+ }
193
+
194
+ public void onBindViewHolder (ViewHolder holder , int position ) {
195
+ switch (getItemViewType (position )) {
196
+ case TYPE_ITEM : {
197
+ ParseObject item = getItem (position );
198
+
199
+ ItemViewHolder vh = (ItemViewHolder ) holder ;
200
+ vh .textView .setText (item .getString ("name" ));
201
+ }
202
+ break ;
203
+ case TYPE_NEXT : {
204
+ NextViewHolder vh = (NextViewHolder ) holder ;
205
+ vh .setLoading (getPager ().isLoadingNextPage ());
206
+ }
207
+ break ;
208
+ }
209
+ }
210
+
211
+ @ Override
212
+ public int getViewTypeCount () {
213
+ return 2 ;
214
+ }
215
+
216
+ @ Override
217
+ public int getItemViewType (int position ) {
218
+ return position < getPager ().getObjects ().size () ? TYPE_ITEM : TYPE_NEXT ;
219
+ }
220
+
221
+ @ Override
222
+ public void registerDataSetObserver (DataSetObserver observer ) {
223
+ super .registerDataSetObserver (observer );
224
+ // We use this method as a notification that the ListView is bound to the adapter.
225
+ loadNextPage ();
226
+ }
227
+
228
+ public static class ViewHolder {
229
+ private View itemView ;
230
+
231
+ public ViewHolder (View itemView ) {
232
+ this .itemView = itemView ;
233
+ }
234
+ }
56
235
}
57
236
}
0 commit comments