1
/*
2
* Copyright 2014 The Android Open Source Project
3
*
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
7
*
8
* http://www.apache.org/licenses/LICENSE-2.0
9
*
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
15
*/
16
17
package com.example.android.swiperefreshmultipleviews;
18
19
import com.example.android.common.dummydata.Cheeses;
20
import com.example.android.common.logger.Log;
21
22
import android.os.AsyncTask;
23
import android.os.Bundle;
24
import android.support.v4.app.Fragment;
25
import android.support.v4.widget.SwipeRefreshLayout;
26
import android.view.LayoutInflater;
27
import android.view.Menu;
28
import android.view.MenuInflater;
29
import android.view.MenuItem;
30
import android.view.View;
31
import android.view.ViewGroup;
32
import android.widget.ArrayAdapter;
33
import android.widget.GridView;
34
35
import java.util.List;
36
37
/**
38
* A sample which shows how to use {@link android.support.v4.widget.SwipeRefreshLayout} to add
39
* the 'swipe-to-refresh' gesture to a layout with multiple children. In this sample,
40
* SwipeRefreshLayout contains a scrollable {@link android.widget.GridView}, along with a
41
* {@link android.widget.TextView} empty view.
42
*
43
* <p>To provide an accessible way to trigger the refresh, this app also provides a refresh
44
* action item.
45
*
46
* <p>In this sample app, the refresh updates the GridView with a random set of new items.
47
*/
48
public class SwipeRefreshMultipleViewsFragment extends Fragment {
49
50
private static final String LOG_TAG = SwipeRefreshMultipleViewsFragment.class.getSimpleName();
51
52
private static final int LIST_ITEM_COUNT = 40;
53
54
/**
55
* The {@link MultiSwipeRefreshLayout} that detects swipe gestures and triggers callbacks in
56
* the app.
57
*/
58
private MultiSwipeRefreshLayout mSwipeRefreshLayout;
59
60
/**
61
* The {@link android.widget.GridView} that displays the content that should be refreshed.
62
*/
63
private GridView mGridView;
64
65
/**
66
* The {@link android.widget.ListAdapter} used to populate the {@link android.widget.GridView}
67
* defined in the previous statement.
68
*/
69
private ArrayAdapter<String> mListAdapter;
70
71
/**
72
* The {@link View} which is displayed when the GridView is empty.
73
*/
74
private View mEmptyView;
75
76
@Override
77
public void onCreate(Bundle savedInstanceState) {
78
super.onCreate(savedInstanceState);
79
80
// Notify the system to allow an options menu for this fragment.
81
setHasOptionsMenu(true);
82
}
83
85
@Override
86
public View onCreateView(LayoutInflater inflater, ViewGroup container,
87
Bundle savedInstanceState) {
88
View view = inflater.inflate(R.layout.fragment_sample, container, false);
89
90
// Retrieve the SwipeRefreshLayout and GridView instances
91
mSwipeRefreshLayout = (MultiSwipeRefreshLayout) view.findViewById(R.id.swiperefresh);
92
94
// Set the color scheme of the SwipeRefreshLayout by providing 4 color resource ids
95
mSwipeRefreshLayout.setColorScheme(
96
R.color.swipe_color_1, R.color.swipe_color_2,
97
R.color.swipe_color_3, R.color.swipe_color_4);
99
100
// Retrieve the GridView
101
mGridView = (GridView) view.findViewById(android.R.id.list);
102
103
// Retrieve the empty view
104
mEmptyView = view.findViewById(android.R.id.empty);
105
106
return view;
107
}
109
111
@Override
112
public void onViewCreated(View view, Bundle savedInstanceState) {
113
super.onViewCreated(view, savedInstanceState);
114
115
/**
116
* Create an ArrayAdapter to contain the data for the GridView. Each item in the GridView
117
* uses the system-defined simple_list_item_1 layout that contains one TextView. Initially
118
*/
119
mListAdapter = new ArrayAdapter<String>(
120
getActivity(),
121
android.R.layout.simple_list_item_1,
122
android.R.id.text1);
123
124
// Set the adapter between the GridView and its backing data.
125
mGridView.setAdapter(mListAdapter);
126
127
// Set the empty view so that it is displayed as needed
128
mGridView.setEmptyView(mEmptyView);
129
131
// Tell the MultiSwipeRefreshLayout which views are swipeable. In this case, the GridView
132
// and empty view.
133
mSwipeRefreshLayout.setSwipeableChildren(android.R.id.list, android.R.id.empty);
135
137
/**
138
* Implement {@link SwipeRefreshLayout.OnRefreshListener}. When users do the "swipe to
139
* refresh" gesture, SwipeRefreshLayout invokes
140
* {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}. In
141
* {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}, call a method that
142
* refreshes the content. Call the same method in response to the Refresh action from the
143
* action bar.
144
*/
145
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
146
@Override
147
public void onRefresh() {
148
Log.i(LOG_TAG, "onRefresh called from SwipeRefreshLayout");
149
150
initiateRefresh();
151
}
152
});
154
}
156
157
@Override
158
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
159
inflater.inflate(R.menu.main_menu, menu);
160
}
161
163
/**
164
* Respond to the user's selection of the Refresh action item. Start the SwipeRefreshLayout
165
* progress bar, then initiate the background task that refreshes the content.
166
*/
167
@Override
168
public boolean onOptionsItemSelected(MenuItem item) {
169
switch (item.getItemId()) {
170
case R.id.menu_clear:
171
Log.i(LOG_TAG, "Clear menu item selected");
172
mListAdapter.clear();
173
return true;
174
175
case R.id.menu_refresh:
176
Log.i(LOG_TAG, "Refresh menu item selected");
177
178
// We make sure that the SwipeRefreshLayout is displaying it's refreshing indicator
179
if (!mSwipeRefreshLayout.isRefreshing()) {
180
mSwipeRefreshLayout.setRefreshing(true);
181
}
182
183
// Start our refresh background task
184
initiateRefresh();
185
186
return true;
187
}
188
189
return super.onOptionsItemSelected(item);
190
}
192
194
/**
195
* By abstracting the refresh process to a single method, the app allows both the
196
* SwipeGestureLayout onRefresh() method and the Refresh action item to refresh the content.
197
*/
198
private void initiateRefresh() {
199
Log.i(LOG_TAG, "initiateRefresh");
200
201
/**
202
* Execute the background task, which uses {@link android.os.AsyncTask} to load the data.
203
*/
204
new DummyBackgroundTask().execute();
205
}
207
209
/**
210
* When the AsyncTask finishes, it calls onRefreshComplete(), which updates the data in the
211
* ListAdapter and turns off the progress bar.
212
*/
213
private void onRefreshComplete(List<String> result) {
214
Log.i(LOG_TAG, "onRefreshComplete");
215
216
// Remove all items from the ListAdapter, and then replace them with the new items
217
mListAdapter.clear();
218
for (String cheese : result) {
219
mListAdapter.add(cheese);
220
}
221
222
// Stop the refreshing indicator
223
mSwipeRefreshLayout.setRefreshing(false);
224
}
226
227
/**
228
* Dummy {@link AsyncTask} which simulates a long running task to fetch new cheeses.
229
*/
230
private class DummyBackgroundTask extends AsyncTask<Void, Void, List<String>> {
231
232
static final int TASK_DURATION = 3 * 1000; // 3 seconds
233
234
@Override
235
protected List<String> doInBackground(Void... params) {
236
// Sleep for a small amount of time to simulate a background-task
237
try {
238
Thread.sleep(TASK_DURATION);
239
} catch (InterruptedException e) {
240
e.printStackTrace();
241
}
242
243
// Return a new random list of cheeses
244
return Cheeses.randomList(LIST_ITEM_COUNT);
245
}
246
247
@Override
248
protected void onPostExecute(List<String> result) {
249
super.onPostExecute(result);
250
251
// Tell the Fragment that the refresh has completed
252
onRefreshComplete(result);
253
}
254
255
}
256
}