blob: 28f91274306bd25044404f8f764bb7d577c8293c [file] [log] [blame]
/*
* Copyright 2015 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.xyztouristattractions.ui;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.example.android.xyztouristattractions.R;
import com.example.android.xyztouristattractions.common.Attraction;
import com.example.android.xyztouristattractions.common.Constants;
import com.example.android.xyztouristattractions.common.Utils;
import com.example.android.xyztouristattractions.provider.TouristAttractions;
import com.example.android.xyztouristattractions.service.UtilityService;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.SphericalUtil;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static com.example.android.xyztouristattractions.provider.TouristAttractions.ATTRACTIONS;
/**
* The main tourist attraction fragment which contains a list of attractions
* sorted by distance (contained inside
* {@link com.example.android.xyztouristattractions.ui.AttractionListActivity}).
*/
public class AttractionListFragment extends Fragment {
private AttractionAdapter mAdapter;
private LatLng mLatestLocation;
private int mImageSize;
public AttractionListFragment() {}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Load a larger size image to make the activity transition to the detail screen smooth
mImageSize = getResources().getDimensionPixelSize(R.dimen.image_size)
* Constants.IMAGE_ANIM_MULTIPLIER;
mLatestLocation = Utils.getLocation(getActivity());
List<Attraction> attractions = loadAttractionsFromLocation(mLatestLocation);
mAdapter = new AttractionAdapter(getActivity(), attractions);
View view = inflater.inflate(R.layout.fragment_main, container, false);
AttractionsRecyclerView recyclerView =
(AttractionsRecyclerView) view.findViewById(android.R.id.list);
recyclerView.setEmptyView(view.findViewById(android.R.id.empty));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(
getActivity(), getResources().getInteger(R.integer.list_columns)));
recyclerView.setAdapter(mAdapter);
return view;
}
@Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
mBroadcastReceiver, UtilityService.getLocationUpdatedIntentFilter());
}
@Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mBroadcastReceiver);
}
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Location location =
intent.getParcelableExtra(FusedLocationProviderApi.KEY_LOCATION_CHANGED);
if (location != null) {
mLatestLocation = new LatLng(location.getLatitude(), location.getLongitude());
mAdapter.mAttractionList = loadAttractionsFromLocation(mLatestLocation);
mAdapter.notifyDataSetChanged();
}
}
};
private static List<Attraction> loadAttractionsFromLocation(final LatLng curLatLng) {
String closestCity = TouristAttractions.getClosestCity(curLatLng);
if (closestCity != null) {
List<Attraction> attractions = ATTRACTIONS.get(closestCity);
if (curLatLng != null) {
Collections.sort(attractions,
new Comparator<Attraction>() {
@Override
public int compare(Attraction lhs, Attraction rhs) {
double lhsDistance = SphericalUtil.computeDistanceBetween(
lhs.location, curLatLng);
double rhsDistance = SphericalUtil.computeDistanceBetween(
rhs.location, curLatLng);
return (int) (lhsDistance - rhsDistance);
}
}
);
}
return attractions;
}
return null;
}
private class AttractionAdapter extends RecyclerView.Adapter<ViewHolder>
implements ItemClickListener {
public List<Attraction> mAttractionList;
private Context mContext;
public AttractionAdapter(Context context, List<Attraction> attractions) {
super();
mContext = context;
mAttractionList = attractions;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.list_row, parent, false);
return new ViewHolder(view, this);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Attraction attraction = mAttractionList.get(position);
holder.mTitleTextView.setText(attraction.name);
holder.mDescriptionTextView.setText(attraction.description);
Glide.with(mContext)
.load(attraction.imageUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.placeholder(R.drawable.empty_photo)
.override(mImageSize, mImageSize)
.into(holder.mImageView);
String distance =
Utils.formatDistanceBetween(mLatestLocation, attraction.location);
if (TextUtils.isEmpty(distance)) {
holder.mOverlayTextView.setVisibility(View.GONE);
} else {
holder.mOverlayTextView.setVisibility(View.VISIBLE);
holder.mOverlayTextView.setText(distance);
}
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return mAttractionList == null ? 0 : mAttractionList.size();
}
@Override
public void onItemClick(View view, int position) {
View heroView = view.findViewById(android.R.id.icon);
DetailActivity.launch(
getActivity(), mAdapter.mAttractionList.get(position).name, heroView);
}
}
private static class ViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
TextView mTitleTextView;
TextView mDescriptionTextView;
TextView mOverlayTextView;
ImageView mImageView;
ItemClickListener mItemClickListener;
public ViewHolder(View view, ItemClickListener itemClickListener) {
super(view);
mTitleTextView = (TextView) view.findViewById(android.R.id.text1);
mDescriptionTextView = (TextView) view.findViewById(android.R.id.text2);
mOverlayTextView = (TextView) view.findViewById(R.id.overlaytext);
mImageView = (ImageView) view.findViewById(android.R.id.icon);
mItemClickListener = itemClickListener;
view.setOnClickListener(this);
}
@Override
public void onClick(View v) {
mItemClickListener.onItemClick(v, getAdapterPosition());
}
}
interface ItemClickListener {
void onItemClick(View view, int position);
}
}