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