Added loading many pages on scroll bottom event.

master
Tomasz Półgrabia 2016-10-04 20:55:40 +02:00
parent c78ebe9614
commit 0b861b0881
6 changed files with 161 additions and 36 deletions

View File

@ -1,6 +1,7 @@
package pl.tpolgrabia.urbanexplorer.adapters; package pl.tpolgrabia.urbanexplorer.adapters;
import android.content.Context; import android.content.Context;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -22,11 +23,9 @@ import java.util.List;
*/ */
public class PlacesAdapter extends ArrayAdapter<GooglePlaceResult> { public class PlacesAdapter extends ArrayAdapter<GooglePlaceResult> {
private final GooglePlacesResponse objects;
public PlacesAdapter(Context context, GooglePlacesResponse objects) { public PlacesAdapter(Context context, List<GooglePlaceResult> objects) {
super(context, R.layout.google_place_item, objects.getPlaces()); super(context, R.layout.google_place_item, objects);
this.objects = objects;
} }
@Override @Override
@ -40,6 +39,10 @@ public class PlacesAdapter extends ArrayAdapter<GooglePlaceResult> {
} }
GooglePlaceResult item = getItem(position); GooglePlaceResult item = getItem(position);
if (item.getId().equals(resultView.getTag())) {
return resultView;
}
final List<GooglePlacePhoto> photos = item.getPhotos(); final List<GooglePlacePhoto> photos = item.getPhotos();
String photoRef = photos != null && !photos.isEmpty() ? photos.get(0).getPhotoReference() : null; String photoRef = photos != null && !photos.isEmpty() ? photos.get(0).getPhotoReference() : null;
String photoUrl = photoRef == null ? null : "https://maps.googleapis.com/maps/api/place/photo?photoreference=" String photoUrl = photoRef == null ? null : "https://maps.googleapis.com/maps/api/place/photo?photoreference="
@ -55,12 +58,16 @@ public class PlacesAdapter extends ArrayAdapter<GooglePlaceResult> {
placeRateWidget.setText("" + item.getRating()); placeRateWidget.setText("" + item.getRating());
ImageView placePreviewWidget = (ImageView)resultView.findViewById(R.id.place_img_preview); ImageView placePreviewWidget = (ImageView)resultView.findViewById(R.id.place_img_preview);
placePreviewWidget.setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.noimage));
ImageLoader.getInstance().displayImage( ImageLoader.getInstance().displayImage(
photoUrl != null ? photoUrl : item.getIcon(), photoUrl != null ? photoUrl : item.getIcon(),
placePreviewWidget, placePreviewWidget,
MainActivity.options); MainActivity.options);
resultView.setTag(item.getId());
return resultView; return resultView;
} }
} }

View File

@ -10,6 +10,9 @@ import java.util.List;
public class GooglePlacesResponse { public class GooglePlacesResponse {
private List<GooglePlaceResult> places; private List<GooglePlaceResult> places;
private String nextPageToken;
private String originalPageToken;
public List<GooglePlaceResult> getPlaces() { public List<GooglePlaceResult> getPlaces() {
return places; return places;
} }
@ -18,10 +21,28 @@ public class GooglePlacesResponse {
this.places = places; this.places = places;
} }
public String getNextPageToken() {
return nextPageToken;
}
public void setNextPageToken(String nextPageToken) {
this.nextPageToken = nextPageToken;
}
public void setOriginalPageToken(String originalPageToken) {
this.originalPageToken = originalPageToken;
}
public String getOriginalPageToken() {
return originalPageToken;
}
@Override @Override
public String toString() { public String toString() {
return "GooglePlacesResponse{" + return "GooglePlacesResponse{" +
"places=" + places + "places=" + places +
", nextPageToken='" + nextPageToken + '\'' +
", originalPageToken='" + originalPageToken + '\'' +
'}'; '}';
} }
} }

View File

@ -8,13 +8,15 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import org.apache.http.HttpStatus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pl.tpolgrabia.googleutils.callback.LocationGeoCoderCallback; import pl.tpolgrabia.googleutils.callback.LocationGeoCoderCallback;
import pl.tpolgrabia.googleutils.callback.PlacesCallback; import pl.tpolgrabia.googleutils.constants.GooglePlacesConstants;
import pl.tpolgrabia.googleutils.dto.GooglePlaceResult; import pl.tpolgrabia.googleutils.dto.GooglePlaceResult;
import pl.tpolgrabia.googleutils.utils.GeocoderUtils; import pl.tpolgrabia.googleutils.utils.GeocoderUtils;
import pl.tpolgrabia.googleutils.utils.PlacesUtils; import pl.tpolgrabia.googleutils.utils.PlacesUtils;
@ -24,11 +26,15 @@ import pl.tpolgrabia.urbanexplorer.MainActivity;
import pl.tpolgrabia.urbanexplorer.R; import pl.tpolgrabia.urbanexplorer.R;
import pl.tpolgrabia.urbanexplorer.adapters.PlacesAdapter; import pl.tpolgrabia.urbanexplorer.adapters.PlacesAdapter;
import pl.tpolgrabia.urbanexplorer.dto.GooglePlacesRequest; import pl.tpolgrabia.urbanexplorer.dto.GooglePlacesRequest;
import pl.tpolgrabia.urbanexplorer.dto.GooglePlacesResponse;
import pl.tpolgrabia.urbanexplorer.handlers.GooglePlacesScrollListener;
import pl.tpolgrabia.urbanexplorer.worker.GooglePlacesWorker; import pl.tpolgrabia.urbanexplorer.worker.GooglePlacesWorker;
import pl.tpolgrabia.urbanexplorerutils.callbacks.StandardLocationListenerCallback; import pl.tpolgrabia.urbanexplorerutils.callbacks.StandardLocationListenerCallback;
import pl.tpolgrabia.urbanexplorerutils.utils.LocationUtils; import pl.tpolgrabia.urbanexplorerutils.utils.LocationUtils;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Semaphore;
/** /**
@ -40,12 +46,22 @@ public class PlacesFragment extends Fragment {
public static final String TAG = PlacesFragment.class.getSimpleName(); public static final String TAG = PlacesFragment.class.getSimpleName();
private PlacesUtils placesUtils; private PlacesUtils placesUtils;
private GeocoderUtils geocoderUtils; private GeocoderUtils geocoderUtils;
private GooglePlacesWorker worker; private String nextPageToken;
private List<GooglePlaceResult> places = new ArrayList<>();
private Semaphore semaphore = new Semaphore(1);
private boolean finished = false;
public PlacesFragment() { public PlacesFragment() {
// Required empty public constructor // Required empty public constructor
} }
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -53,6 +69,9 @@ public class PlacesFragment extends Fragment {
// Inflate the layout for this fragment // Inflate the layout for this fragment
final View inflatedView = inflater.inflate(R.layout.fragment_places, container, false); final View inflatedView = inflater.inflate(R.layout.fragment_places, container, false);
ListView placesWidget = (ListView) inflatedView.findViewById(R.id.google_places);
placesWidget.setOnScrollListener(new GooglePlacesScrollListener(this));
return inflatedView; return inflatedView;
} }
@ -103,7 +122,6 @@ public class PlacesFragment extends Fragment {
}); });
geocoderUtils = new GeocoderUtils(getActivity(), AppConstants.GOOGLE_API_KEY); geocoderUtils = new GeocoderUtils(getActivity(), AppConstants.GOOGLE_API_KEY);
worker = new GooglePlacesWorker(getActivity(), this);
} }
@ -139,30 +157,73 @@ public class PlacesFragment extends Fragment {
} }
private void fetchNearbyPlacesAndPresemt(Location location) { private void fetchNearbyPlacesAndPresemt(Location location) {
if (!semaphore.tryAcquire()) {
// running
return;
}
GooglePlacesRequest request = new GooglePlacesRequest(); GooglePlacesRequest request = new GooglePlacesRequest();
request.setLocation(location); request.setLocation(location);
request.setSearchRadius(AppConstants.DEF_PLACES_RADIUS); request.setSearchRadius(AppConstants.DEF_PLACES_RADIUS);
request.setSearchItemType("museum"); request.setSearchItemType(GooglePlacesConstants.PLACES_SEARCH_TYPE);
worker.execute(request); new GooglePlacesWorker(getActivity(), this).execute(request);
}
// placesUtils.fetchNearbyPlaces( public void loadNextPage() {
// location.getLatitude(),
// location.getLongitude(), if (!semaphore.tryAcquire()) {
// AppConstants.DEF_PLACES_RADIUS, // running
// "museum", return;
// null, }
// new PlacesCallback() {
// @Override if (finished) {
// public void callback(Long statusCode, String statusMsg, List<GooglePlaceResult> googlePlaceResult) { semaphore.release();
// lg.debug("Fetch nearby statusCode: {}, status message: {}, google result: {}", return;
// statusCode, }
// statusMsg,
// googlePlaceResult); lg.debug("Loading next page");
//
// ListView googlePlacesWidget = (ListView) getView().findViewById(R.id.google_places); Location location = LocationUtils.getLastKnownLocation(getActivity());
// PlacesAdapter adapter = new PlacesAdapter(getActivity(), googlePlaceResult); GooglePlacesRequest request = new GooglePlacesRequest();
// googlePlacesWidget.setAdapter(adapter); request.setLocation(location);
// } request.setSearchRadius(AppConstants.DEF_PLACES_RADIUS);
// }); request.setSearchItemType(GooglePlacesConstants.PLACES_SEARCH_TYPE);
request.setPageToken(nextPageToken);
new GooglePlacesWorker(getActivity(), this).execute(request);
}
public void setNextPageToken(String nextPageToken) {
this.nextPageToken = nextPageToken;
}
@Subscribe
public void handleGooglePlacesResult(GooglePlacesResponse response) {
lg.debug("Handling google places results with original {} and next page token {}",
response.getOriginalPageToken(),
response.getNextPageToken());
ListView placesWidget = (ListView) getView().findViewById(R.id.google_places);
if (nextPageToken == null) {
places = response.getPlaces();
PlacesAdapter adapter = new PlacesAdapter(getActivity(), places);
placesWidget.setAdapter(adapter);
} else {
places.addAll(response.getPlaces());
PlacesAdapter adapter = (PlacesAdapter)placesWidget.getAdapter();
adapter.addAll(places);
}
nextPageToken = response.getNextPageToken();
if (nextPageToken == null) {
finished = true;
}
semaphore.release();
}
@Override
public void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
} }
} }

View File

@ -0,0 +1,29 @@
package pl.tpolgrabia.urbanexplorer.handlers;
import android.widget.AbsListView;
import pl.tpolgrabia.urbanexplorer.fragments.PlacesFragment;
/**
* Created by tpolgrabia on 04.10.16.
*/
public class GooglePlacesScrollListener implements AbsListView.OnScrollListener {
private final PlacesFragment placesFragment;
public GooglePlacesScrollListener(PlacesFragment placesFragment) {
this.placesFragment = placesFragment;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem + visibleItemCount >= totalItemCount) {
// scrolled to the bottom, loading new page
placesFragment.loadNextPage();
}
}
}

View File

@ -6,6 +6,7 @@ import android.os.AsyncTask;
import android.view.View; import android.view.View;
import android.widget.ListView; import android.widget.ListView;
import org.apache.http.HttpStatus; import org.apache.http.HttpStatus;
import org.greenrobot.eventbus.EventBus;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import pl.tpolgrabia.googleutils.callback.PlacesCallback; import pl.tpolgrabia.googleutils.callback.PlacesCallback;
@ -53,6 +54,7 @@ public class GooglePlacesWorker extends AsyncTask<GooglePlacesRequest, Integer,
for (final GooglePlacesRequest param : params) { for (final GooglePlacesRequest param : params) {
lg.debug("Excuting param {}", param); lg.debug("Excuting param {}", param);
lg.debug("Fetching page with token {}", param.getPageToken());
Location location = param.getLocation(); Location location = param.getLocation();
Response<GooglePlaceResponse> placesResponse = null; Response<GooglePlaceResponse> placesResponse = null;
@ -67,6 +69,8 @@ public class GooglePlacesWorker extends AsyncTask<GooglePlacesRequest, Integer,
if (placesResponse != null && placesResponse.code() == HttpStatus.SC_OK) { if (placesResponse != null && placesResponse.code() == HttpStatus.SC_OK) {
GooglePlacesResponse response = new GooglePlacesResponse(); GooglePlacesResponse response = new GooglePlacesResponse();
response.setPlaces(placesResponse.body().getResults()); response.setPlaces(placesResponse.body().getResults());
response.setNextPageToken(placesResponse.body().getNextPageToken());
response.setOriginalPageToken(param.getPageToken());
result.add(response); result.add(response);
} }
@ -83,15 +87,17 @@ public class GooglePlacesWorker extends AsyncTask<GooglePlacesRequest, Integer,
@Override @Override
protected void onPostExecute(List<GooglePlacesResponse> googlePlacesResponses) { protected void onPostExecute(List<GooglePlacesResponse> googlePlacesResponses) {
lg.debug("Post execute {}", googlePlacesResponses); lg.debug("Post execute {}", googlePlacesResponses);
final View view = placesFragment.getView(); // final View view = placesFragment.getView();
if (view == null) { // if (view == null) {
lg.error("Fragment not attached to the view"); // lg.error("Fragment not attached to the view");
return; // return;
} // }
for (GooglePlacesResponse response : googlePlacesResponses) { for (GooglePlacesResponse response : googlePlacesResponses) {
ListView places = (ListView) view.findViewById(R.id.google_places); // placesFragment.setNextPageToken(response.getNextPageToken());
places.setAdapter(new PlacesAdapter(ctx, response)); // ListView places = (ListView) view.findViewById(R.id.google_places);
EventBus.getDefault().post(response);
// places.setAdapter(new PlacesAdapter(ctx, response));
} }
} }
} }

View File

@ -7,4 +7,5 @@ public class GooglePlacesConstants {
public static final String GOOGLE_PLACES_BASEURL = "https://maps.googleapis.com/maps/api/place/"; public static final String GOOGLE_PLACES_BASEURL = "https://maps.googleapis.com/maps/api/place/";
public static final Long PHOTO_MAX_WIDTH = 512L; public static final Long PHOTO_MAX_WIDTH = 512L;
public static final String GOOGLE_MAPS_PLACES_API_BASEURL = "https://maps.googleapis.com/maps/api/place/"; public static final String GOOGLE_MAPS_PLACES_API_BASEURL = "https://maps.googleapis.com/maps/api/place/";
public static final String PLACES_SEARCH_TYPE = "museum";
} }