/* * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.agera.basicsamplewithoutcallbacks; import static java.util.concurrent.Executors.newSingleThreadExecutor; import com.google.android.agera.Observable; import com.google.android.agera.Repositories; import com.google.android.agera.Repository; import com.google.android.agera.Result; import com.google.android.agera.Updatable; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; import android.support.v4.widget.SwipeRefreshLayout; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.Toast; import java.util.List; import java.util.concurrent.ExecutorService; /** * The MainFragment contains a {@link ListView} that displays a list of usernames. The usernames * are loaded in {@link Fragment#onResume()} and there is a {@link SwipeRefreshLayout} allowing the * user to manually refresh the list of usernames. * <P > * This is set up as an {@link Updatable} as changes in the {@link #usernamesRepository} should * trigger the MainFragment to redraw itself. */ public class MainFragment extends Fragment implements Updatable { /** * The {@link SwipeRefreshLayout.OnRefreshListener} is also an {@link Observable}. It is * observed by the {@link #usernamesRepository}, an update is triggered whenever * {@link SwipeRefreshLayout.OnRefreshListener#onRefresh()} is fired. */ private OnRefreshObservable refreshObservable; /** * The usernames repository takes care of providing the data to this fragment. It is created * using Agera's repository compiler. * * @see #setUpRepository() */ private Repository<Result<List<String>>> usernamesRepository; private ListAdapter listAdapter; private ListView listView; private SwipeRefreshLayout swipeRefreshLayout; private ExecutorService networkExecutor; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.main_frag, container, false); listView = (ListView) root.findViewById(R.id.list); // Set pull to refresh as an observable and attach it to the view refreshObservable = new OnRefreshObservable(); swipeRefreshLayout = (SwipeRefreshLayout) root.findViewById(R.id.refresh_layout); swipeRefreshLayout.setColorSchemeColors( ContextCompat.getColor(getActivity(), R.color.colorPrimary), ContextCompat.getColor(getActivity(), R.color.colorAccent), ContextCompat.getColor(getActivity(), R.color.colorPrimaryDark)); swipeRefreshLayout.setOnRefreshListener(refreshObservable); setUpRepository(); return root; } private void setUpRepository() { // Set up background executor networkExecutor = newSingleThreadExecutor(); // Set up usernames repository usernamesRepository = Repositories .repositoryWithInitialValue(Result.<List<String>>absent()) .observe(refreshObservable) .onUpdatesPerLoop() .goTo(networkExecutor) .thenGetFrom(new UsernamesSupplier()) .compile(); } @Override public void onResume() { super.onResume(); // We make sure the main fragment observes the repository. This will also trigger the // repository to update itself. usernamesRepository.addUpdatable(this); // We update the UI to show the data is being updated. We need to wait for the // SwipeRefreshLayout to be ready before asking it to show itself as refreshing. swipeRefreshLayout.post(new Runnable() { @Override public void run() { update(); } }); } @Override public void onPause() { super.onPause(); // We remove the observations to avoid triggering updates when they aren't needed usernamesRepository.removeUpdatable(this); } /** * As this MainFragment is observing the {@link #usernamesRepository}, this is triggered * whenever the {@link #usernamesRepository} updates itself. */ @Override public void update() { // Result has methods to differentiate between success and failure. // Process Result.isAbsent() first because Result.failed() is true if Result.isAbsent() is // true. if (usernamesRepository.get().isAbsent()) { swipeRefreshLayout.setRefreshing(true); } else if (usernamesRepository.get().failed()) { // Show error message, do not update list as we still want to show the last known list // of usernames Toast.makeText(getContext(), getResources().getString(R.string.error), Toast.LENGTH_LONG).show(); swipeRefreshLayout.setRefreshing(false); } else { // Success // Update the list of usernames listAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, usernamesRepository.get().get()); listView.setAdapter(listAdapter); swipeRefreshLayout.setRefreshing(false); } } }