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.swiperefreshlistfragment; 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.widget.SwipeRefreshLayout; 25 import android.view.Menu; 26 import android.view.MenuInflater; 27 import android.view.MenuItem; 28 import android.view.View; 29 import android.widget.ArrayAdapter; 30 import android.widget.ListAdapter; 31 32 import java.util.List; 33 34 /** 35 * A sample which shows how to use {@link android.support.v4.widget.SwipeRefreshLayout} within a 36 * {@link android.support.v4.app.ListFragment} to add the 'swipe-to-refresh' gesture to a 37 * {@link android.widget.ListView}. This is provided through the provided re-usable 38 * {@link SwipeRefreshListFragment} class. 39 * 40 * <p>To provide an accessible way to trigger the refresh, this app also provides a refresh 41 * action item. This item should be displayed in the Action Bar's overflow item. 42 * 43 * <p>In this sample app, the refresh updates the ListView with a random set of new items. 44 * 45 * <p>This sample also provides the functionality to change the colors displayed in the 46 * {@link android.support.v4.widget.SwipeRefreshLayout} through the options menu. This is meant to 47 * showcase the use of color rather than being something that should be integrated into apps. 48 */ 49 public class SwipeRefreshListFragmentFragment extends SwipeRefreshListFragment { 50 51 private static final String LOG_TAG = SwipeRefreshListFragmentFragment.class.getSimpleName(); 52 53 private static final int LIST_ITEM_COUNT = 20; 54 55 @Override 56 public void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 59 // Notify the system to allow an options menu for this fragment. 60 setHasOptionsMenu(true); 61 } 62 64 @Override 65 public void onViewCreated(View view, Bundle savedInstanceState) { 66 super.onViewCreated(view, savedInstanceState); 67 68 /** 69 * Create an ArrayAdapter to contain the data for the ListView. Each item in the ListView 70 * uses the system-defined simple_list_item_1 layout that contains one TextView. 71 */ 72 ListAdapter adapter = new ArrayAdapter<String>( 73 getActivity(), 74 android.R.layout.simple_list_item_1, 75 android.R.id.text1, 76 Cheeses.randomList(LIST_ITEM_COUNT)); 77 78 // Set the adapter between the ListView and its backing data. 79 setListAdapter(adapter); 80 82 /** 83 * Implement {@link SwipeRefreshLayout.OnRefreshListener}. When users do the "swipe to 84 * refresh" gesture, SwipeRefreshLayout invokes 85 * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}. In 86 * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh onRefresh()}, call a method that 87 * refreshes the content. Call the same method in response to the Refresh action from the 88 * action bar. 89 */ 90 setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 91 @Override 92 public void onRefresh() { 93 Log.i(LOG_TAG, "onRefresh called from SwipeRefreshLayout"); 94 95 initiateRefresh(); 96 } 97 }); 99 } 101 102 @Override 103 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 104 inflater.inflate(R.menu.main_menu, menu); 105 } 106 108 /** 109 * Respond to the user's selection of the Refresh action item. Start the SwipeRefreshLayout 110 * progress bar, then initiate the background task that refreshes the content. 111 * 112 * <p>A color scheme menu item used for demonstrating the use of SwipeRefreshLayout's color 113 * scheme functionality. This kind of menu item should not be incorporated into your app, 114 * it just to demonstrate the use of color. Instead you should choose a color scheme based 115 * off of your application's branding. 116 */ 117 @Override 118 public boolean onOptionsItemSelected(MenuItem item) { 119 switch (item.getItemId()) { 120 case R.id.menu_refresh: 121 Log.i(LOG_TAG, "Refresh menu item selected"); 122 123 // We make sure that the SwipeRefreshLayout is displaying it's refreshing indicator 124 if (!isRefreshing()) { 125 setRefreshing(true); 126 } 127 128 // Start our refresh background task 129 initiateRefresh(); 130 return true; 131 132 case R.id.menu_color_scheme_1: 133 Log.i(LOG_TAG, "setColorScheme #1"); 134 item.setChecked(true); 135 136 // Change the colors displayed by the SwipeRefreshLayout by providing it with 4 137 // color resource ids 138 setColorScheme(R.color.color_scheme_1_1, R.color.color_scheme_1_2, 139 R.color.color_scheme_1_3, R.color.color_scheme_1_4); 140 return true; 141 142 case R.id.menu_color_scheme_2: 143 Log.i(LOG_TAG, "setColorScheme #2"); 144 item.setChecked(true); 145 146 // Change the colors displayed by the SwipeRefreshLayout by providing it with 4 147 // color resource ids 148 setColorScheme(R.color.color_scheme_2_1, R.color.color_scheme_2_2, 149 R.color.color_scheme_2_3, R.color.color_scheme_2_4); 150 return true; 151 152 case R.id.menu_color_scheme_3: 153 Log.i(LOG_TAG, "setColorScheme #3"); 154 item.setChecked(true); 155 156 // Change the colors displayed by the SwipeRefreshLayout by providing it with 4 157 // color resource ids 158 setColorScheme(R.color.color_scheme_3_1, R.color.color_scheme_3_2, 159 R.color.color_scheme_3_3, R.color.color_scheme_3_4); 160 return true; 161 } 162 163 return super.onOptionsItemSelected(item); 164 } 166 168 /** 169 * By abstracting the refresh process to a single method, the app allows both the 170 * SwipeGestureLayout onRefresh() method and the Refresh action item to refresh the content. 171 */ 172 private void initiateRefresh() { 173 Log.i(LOG_TAG, "initiateRefresh"); 174 175 /** 176 * Execute the background task, which uses {@link android.os.AsyncTask} to load the data. 177 */ 178 new DummyBackgroundTask().execute(); 179 } 181 183 /** 184 * When the AsyncTask finishes, it calls onRefreshComplete(), which updates the data in the 185 * ListAdapter and turns off the progress bar. 186 */ 187 private void onRefreshComplete(List<String> result) { 188 Log.i(LOG_TAG, "onRefreshComplete"); 189 190 // Remove all items from the ListAdapter, and then replace them with the new items 191 ArrayAdapter<String> adapter = (ArrayAdapter<String>) getListAdapter(); 192 adapter.clear(); 193 for (String cheese : result) { 194 adapter.add(cheese); 195 } 196 197 // Stop the refreshing indicator 198 setRefreshing(false); 199 } 201 202 /** 203 * Dummy {@link AsyncTask} which simulates a long running task to fetch new cheeses. 204 */ 205 private class DummyBackgroundTask extends AsyncTask<Void, Void, List<String>> { 206 207 static final int TASK_DURATION = 3 * 1000; // 3 seconds 208 209 @Override 210 protected List<String> doInBackground(Void... params) { 211 // Sleep for a small amount of time to simulate a background-task 212 try { 213 Thread.sleep(TASK_DURATION); 214 } catch (InterruptedException e) { 215 e.printStackTrace(); 216 } 217 218 // Return a new random list of cheeses 219 return Cheeses.randomList(LIST_ITEM_COUNT); 220 } 221 222 @Override 223 protected void onPostExecute(List<String> result) { 224 super.onPostExecute(result); 225 226 // Tell the Fragment that the refresh has completed 227 onRefreshComplete(result); 228 } 229 230 } 231 232 }