diff --git a/MyTracks/res/layout/list_item.xml b/MyTracks/res/layout/list_item.xml index 44037c377..28d559265 100644 --- a/MyTracks/res/layout/list_item.xml +++ b/MyTracks/res/layout/list_item.xml @@ -14,92 +14,78 @@ 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. --> - - - - - - - - + + + + + + - - - - - - - - - - - + android:layout_marginLeft="8dp" + android:layout_marginRight="8dp" + android:layout_width="wrap_content" /> + + android:layout_width="match_parent" + android:shrinkColumns="0" + android:stretchColumns="0" > + + + - - - - - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java index c544891fa..83ac0224f 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/MarkerDetailFragment.java @@ -101,7 +101,7 @@ public class MarkerDetailFragment extends Fragment { inflater.inflate(R.menu.marker_detail, menu); updateWaypoint(false); - + Track track = myTracksProviderUtils.getTrack(waypoint.getTrackId()); boolean isSharedWithMe = track != null ? track.isSharedWithMe() : true; @@ -114,7 +114,7 @@ public class MarkerDetailFragment extends Fragment { long markerId = getArguments().getLong(KEY_MARKER_ID); FragmentActivity fragmentActivity = getActivity(); Intent intent; - + switch (item.getItemId()) { case R.id.marker_detail_show_on_map: intent = IntentUtils.newIntent(fragmentActivity, TrackDetailActivity.class) @@ -168,11 +168,8 @@ public class MarkerDetailFragment extends Fragment { } else { imageView.setVisibility(View.VISIBLE); Display defaultDisplay = getActivity().getWindowManager().getDefaultDisplay(); - @SuppressWarnings("deprecation") - int displayWidth = defaultDisplay.getWidth(); - @SuppressWarnings("deprecation") - int displayHeight = defaultDisplay.getHeight(); - PhotoUtils.setImageVew(imageView, Uri.parse(photoUrl), displayWidth, displayHeight); + PhotoUtils.setImageVew(imageView, Uri.parse(photoUrl), defaultDisplay.getWidth(), + defaultDisplay.getHeight(), true); } TextView name = (TextView) getView().findViewById(R.id.marker_detail_waypoint_name); @@ -193,8 +190,8 @@ public class MarkerDetailFragment extends Fragment { TextView name = (TextView) getView().findViewById(R.id.marker_detail_statistics_name); name.setText(getString(R.string.generic_name_line, waypoint.getName())); - StatsUtils.setTripStatisticsValues(getActivity(), waypoint.getTripStatistics(), - PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); + StatsUtils.setTripStatisticsValues( + getActivity(), waypoint.getTripStatistics(), PreferencesUtils.RECORDING_TRACK_ID_DEFAULT); StatsUtils.setLocationValues(getActivity(), waypoint.getLocation(), false); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/BitmapLoader.java b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/BitmapLoader.java index 2513e4d7b..995b665a3 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/tasks/BitmapLoader.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/tasks/BitmapLoader.java @@ -40,16 +40,19 @@ public class BitmapLoader extends AsyncTask { private final WeakReference imageViewReference; private final Uri uri; - private final int displayWidth; - private final int displayHeight; + private final int targetWidth; + private final int targetHeight; + private final boolean fitWithin; - public BitmapLoader(ImageView imageView, Uri uri, int displayWidth, int displayHeight) { + public BitmapLoader( + ImageView imageView, Uri uri, int targetWidth, int targetHeight, boolean fitWithin) { // Use a WeakReference to ensure the ImageView can be garbage collected imageViewReference = new WeakReference(imageView); this.uri = uri; - this.displayWidth = displayWidth; - this.displayHeight = displayHeight; + this.targetWidth = targetWidth; + this.targetHeight = targetHeight; + this.fitWithin = fitWithin; } public Uri getUri() { @@ -65,13 +68,6 @@ public class BitmapLoader extends AsyncTask { options.inJustDecodeBounds = true; BitmapFactory.decodeFile(uri.getPath(), options); - // Set targetWidth and targetHeight - int targetWidth = displayWidth; - int targetHeight = displayHeight; - if (targetHeight == 0) { - targetHeight = (int) (targetWidth * ((float) options.outHeight / (float) options.outWidth)); - } - // Set imageWidth and imageHeight based on image rotation int rotation = getRotation(); int imageWidth; @@ -87,20 +83,26 @@ public class BitmapLoader extends AsyncTask { // Get a scaled down version of the image options.inJustDecodeBounds = false; - options.inSampleSize = getInSampleSize(imageWidth, imageHeight, targetWidth, targetHeight); + options.inSampleSize = getInSampleSize(imageWidth, imageHeight); options.inPurgeable = true; Bitmap scaledBitmap = BitmapFactory.decodeFile(uri.getPath(), options); // Get the final bitmap after rotating the scaled down image Bitmap bitmap; - if (rotation == 0) { + if (rotation == 0 && fitWithin) { bitmap = scaledBitmap; } else { Matrix matrix = new Matrix(); matrix.postRotate(rotation); + int offset = 0; + int height = scaledBitmap.getHeight(); + if (!fitWithin && height > targetHeight) { + offset = (height - targetHeight) / 2; + height = targetHeight; + } bitmap = Bitmap.createBitmap( - scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true); + scaledBitmap, 0, offset, scaledBitmap.getWidth(), height, matrix, true); scaledBitmap.recycle(); } return bitmap; @@ -148,10 +150,8 @@ public class BitmapLoader extends AsyncTask { * * @param imageWidth the image width * @param imageHeight the image height - * @param targetWidth the target width - * @param targetHeight the target height */ - private int getInSampleSize(int imageWidth, int imageHeight, int targetWidth, int targetHeight) { + private int getInSampleSize(int imageWidth, int imageHeight) { float widthRatio = 1; if (imageWidth > targetWidth) { widthRatio = (float) imageWidth / (float) targetWidth; @@ -162,11 +162,21 @@ public class BitmapLoader extends AsyncTask { heightRatio = (float) imageHeight / (float) targetHeight; } - /* - * To fit within the target area, return the larger sample ratio so the - * image will not be larger than the target dimensions. Use Math.floor to - * not under sample. - */ - return (int) Math.floor(Math.max(widthRatio, heightRatio)); + double size; + if (fitWithin) { + /* + * To fit within the target area, return the larger sample ratio so the + * image will not be larger than the target dimensions. + */ + size = Math.max(widthRatio, heightRatio); + } else { + /* + * To fill the target area, return the smaller ratio so the image will + * cover both dimensions. + */ + size = Math.min(widthRatio, heightRatio); + } + // Use Math.floor to not under-sample. + return (int) Math.floor(size); } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java index c4efb3ec1..1950bcb82 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ListItemUtils.java @@ -20,6 +20,7 @@ import com.google.android.maps.mytracks.R; import android.app.Activity; import android.content.Context; +import android.content.res.TypedArray; import android.net.Uri; import android.text.format.DateUtils; import android.view.Display; @@ -36,6 +37,8 @@ import java.util.Calendar; */ public class ListItemUtils { + private static final int LIST_PREFERRED_ITEM_HEIGHT_DEFAULT = 128; + private ListItemUtils() {} /** @@ -87,17 +90,14 @@ public class ListItemUtils { setTextView(timeDistanceTextView, getTimeDistance(activity, isRecording, isPaused, sharedOwner, totalTime, totalDistance)); - // Set photoUrl - ImageView photo = (ImageView) view.findViewById(R.id.list_item_photo); + ImageView photo = (ImageView) view.findViewById(R.id.list_item_background); if (photoUrl == null || photoUrl.equals("")) { photo.setVisibility(View.GONE); } else { photo.setVisibility(View.VISIBLE); Display defaultDisplay = activity.getWindowManager().getDefaultDisplay(); - // Set the initial width to 33% of the display width. - int width = (int) (defaultDisplay.getWidth() * .33); - int height = 0; - PhotoUtils.setImageVew(photo, Uri.parse(photoUrl), width, height); + PhotoUtils.setImageVew( + photo, Uri.parse(photoUrl), defaultDisplay.getWidth(), getPhotoHeight(activity), false); } // Set date/time @@ -108,6 +108,15 @@ public class ListItemUtils { TextView timeTextView = (TextView) view.findViewById(R.id.list_item_time); setTextView(timeTextView, startTimeDisplay[1]); + /* + * If column0 is GONE, change to INVISIBLE so column1 is placed at the + * correct position. + */ + if (timeTextView.getVisibility() == View.VISIBLE + && timeDistanceTextView.getVisibility() == View.GONE) { + timeDistanceTextView.setVisibility(View.INVISIBLE); + } + // Set category/description TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description); setTextView(descriptionTextView, @@ -201,4 +210,17 @@ public class ListItemUtils { textView.setText(value); } } + + /** + * Gets the photo height. + * + * @param context the context + */ + private static int getPhotoHeight(Context context) { + int[] attrs = new int[] { android.R.attr.listPreferredItemHeight }; + TypedArray typeArray = context.obtainStyledAttributes(attrs); + int height = typeArray.getDimensionPixelSize(0, LIST_PREFERRED_ITEM_HEIGHT_DEFAULT); + typeArray.recycle(); + return 2 * height; + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/PhotoUtils.java b/MyTracks/src/com/google/android/apps/mytracks/util/PhotoUtils.java index 80da1d43d..59abcfe6e 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/PhotoUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/PhotoUtils.java @@ -37,13 +37,17 @@ public class PhotoUtils { * * @param imageView the image view * @param uri the image uri - * @param displayWidth the display width - * @param displayHeight the display height + * @param targetWidth the target width + * @param targetHeight the target height + * @param fitWithin true to fit within the target area in order to display the + * entire image (no cropping). False to fill the entire target area. + * (allow cropping). */ public static void setImageVew( - ImageView imageView, Uri uri, int displayWidth, int displayHeight) { + ImageView imageView, Uri uri, int targetWidth, int targetHeight, boolean fitWithin) { if (cancelBitmapLoader(imageView, uri)) { - BitmapLoader bitmapLoader = new BitmapLoader(imageView, uri, displayWidth, displayHeight); + BitmapLoader bitmapLoader = new BitmapLoader( + imageView, uri, targetWidth, targetHeight, fitWithin); WeakReference bitmapLoaderReference = new WeakReference( bitmapLoader); imageView.setTag(bitmapLoaderReference);