1 /* 2 * Copyright 2015 Google Inc. All rights reserved. 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.xyztouristattractions.ui; 18 19 import android.app.TaskStackBuilder; 20 import android.content.Intent; 21 import android.net.Uri; 22 import android.os.Build; 23 import android.os.Bundle; 24 import android.support.design.widget.FloatingActionButton; 25 import android.support.v4.app.Fragment; 26 import android.support.v4.app.NavUtils; 27 import android.text.TextUtils; 28 import android.view.LayoutInflater; 29 import android.view.MenuItem; 30 import android.view.View; 31 import android.view.ViewGroup; 32 import android.widget.ImageView; 33 import android.widget.TextView; 34 35 import com.bumptech.glide.Glide; 36 import com.bumptech.glide.load.engine.DiskCacheStrategy; 37 import com.example.android.xyztouristattractions.R; 38 import com.example.android.xyztouristattractions.common.Attraction; 39 import com.example.android.xyztouristattractions.common.Constants; 40 import com.example.android.xyztouristattractions.common.Utils; 41 import com.google.android.gms.maps.model.LatLng; 42 43 import java.util.List; 44 import java.util.Map; 45 46 import static com.example.android.xyztouristattractions.provider.TouristAttractions.ATTRACTIONS; 47 48 /** 49 * The tourist attraction detail fragment which contains the details of a 50 * a single attraction (contained inside 51 * {@link com.example.android.xyztouristattractions.ui.DetailActivity}). 52 */ 53 public class DetailFragment extends Fragment { 54 55 private static final String EXTRA_ATTRACTION = "attraction"; 56 private Attraction mAttraction; 57 createInstance(String attractionName)58 public static DetailFragment createInstance(String attractionName) { 59 DetailFragment detailFragment = new DetailFragment(); 60 Bundle bundle = new Bundle(); 61 bundle.putString(EXTRA_ATTRACTION, attractionName); 62 detailFragment.setArguments(bundle); 63 return detailFragment; 64 } 65 DetailFragment()66 public DetailFragment() {} 67 68 @Override onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)69 public View onCreateView(LayoutInflater inflater, ViewGroup container, 70 Bundle savedInstanceState) { 71 setHasOptionsMenu(true); 72 View view = inflater.inflate(R.layout.fragment_detail, container, false); 73 String attractionName = getArguments().getString(EXTRA_ATTRACTION); 74 mAttraction = findAttraction(attractionName); 75 76 if (mAttraction == null) { 77 getActivity().finish(); 78 return null; 79 } 80 81 TextView nameTextView = (TextView) view.findViewById(R.id.nameTextView); 82 TextView descTextView = (TextView) view.findViewById(R.id.descriptionTextView); 83 TextView distanceTextView = (TextView) view.findViewById(R.id.distanceTextView); 84 ImageView imageView = (ImageView) view.findViewById(R.id.imageView); 85 FloatingActionButton mapFab = (FloatingActionButton) view.findViewById(R.id.mapFab); 86 87 LatLng location = Utils.getLocation(getActivity()); 88 String distance = Utils.formatDistanceBetween(location, mAttraction.location); 89 if (TextUtils.isEmpty(distance)) { 90 distanceTextView.setVisibility(View.GONE); 91 } 92 93 nameTextView.setText(attractionName); 94 distanceTextView.setText(distance); 95 descTextView.setText(mAttraction.longDescription); 96 97 int imageSize = getResources().getDimensionPixelSize(R.dimen.image_size) 98 * Constants.IMAGE_ANIM_MULTIPLIER; 99 Glide.with(getActivity()) 100 .load(mAttraction.imageUrl) 101 .diskCacheStrategy(DiskCacheStrategy.SOURCE) 102 .placeholder(R.color.lighter_gray) 103 .override(imageSize, imageSize) 104 .into(imageView); 105 106 mapFab.setOnClickListener(new View.OnClickListener() { 107 @Override 108 public void onClick(View v) { 109 Intent intent = new Intent(Intent.ACTION_VIEW); 110 intent.setData(Uri.parse(Constants.MAPS_INTENT_URI + 111 Uri.encode(mAttraction.name + ", " + mAttraction.city))); 112 startActivity(intent); 113 } 114 }); 115 116 return view; 117 } 118 119 @Override onOptionsItemSelected(MenuItem item)120 public boolean onOptionsItemSelected(MenuItem item) { 121 switch (item.getItemId()) { 122 case android.R.id.home: 123 // Some small additions to handle "up" navigation correctly 124 Intent upIntent = NavUtils.getParentActivityIntent(getActivity()); 125 upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); 126 127 // Check if up activity needs to be created (usually when 128 // detail screen is opened from a notification or from the 129 // Wearable app 130 if (NavUtils.shouldUpRecreateTask(getActivity(), upIntent) 131 || getActivity().isTaskRoot()) { 132 133 // Synthesize parent stack 134 TaskStackBuilder.create(getActivity()) 135 .addNextIntentWithParentStack(upIntent) 136 .startActivities(); 137 } 138 139 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 140 // On Lollipop+ we finish so to run the nice animation 141 getActivity().finishAfterTransition(); 142 return true; 143 } 144 145 // Otherwise let the system handle navigating "up" 146 return false; 147 } 148 return super.onOptionsItemSelected(item); 149 } 150 151 /** 152 * Really hacky loop for finding attraction in our static content provider. 153 * Obviously would not be used in a production app. 154 */ findAttraction(String attractionName)155 private Attraction findAttraction(String attractionName) { 156 for (Map.Entry<String, List<Attraction>> attractionsList : ATTRACTIONS.entrySet()) { 157 List<Attraction> attractions = attractionsList.getValue(); 158 for (Attraction attraction : attractions) { 159 if (attractionName.equals(attraction.name)) { 160 return attraction; 161 } 162 } 163 } 164 return null; 165 } 166 } 167