mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-08 20:33:06 +02:00
display photos in marker list
This commit is contained in:
@@ -18,8 +18,11 @@ package com.google.android.apps.mytracks.util;
|
||||
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.text.format.DateUtils;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
@@ -38,23 +41,25 @@ public class ListItemUtils {
|
||||
/**
|
||||
* Sets a list item.
|
||||
*
|
||||
* @param context the context
|
||||
* @param activity the activity
|
||||
* @param view the list item view
|
||||
* @param isRecording true if recording
|
||||
* @param isPaused true if paused
|
||||
* @param name the name value
|
||||
* @param iconId the icon id
|
||||
* @param iconContentDescriptionId the icon content description id
|
||||
* @param category the category value
|
||||
* @param name the name value
|
||||
* @param sharedOwner if shared with me track, the owner, else null
|
||||
* @param totalTime the total time value
|
||||
* @param totalDistance the total distance value
|
||||
* @param photoUrl the photo url
|
||||
* @param startTime the start time value
|
||||
* @param category the category value
|
||||
* @param description the description value
|
||||
* @param sharedOwner if shared with me track, the owner, else null
|
||||
*/
|
||||
public static void setListItem(Context context, View view, boolean isRecording, boolean isPaused,
|
||||
int iconId, int iconContentDescriptionId, String name, String category, String totalTime,
|
||||
String totalDistance, long startTime, String description, String sharedOwner) {
|
||||
public static void setListItem(Activity activity, View view, boolean isRecording,
|
||||
boolean isPaused, int iconId, int iconContentDescriptionId, String name, String sharedOwner,
|
||||
String totalTime, String totalDistance, String photoUrl, long startTime, String category,
|
||||
String description) {
|
||||
|
||||
if (isRecording) {
|
||||
iconId = isPaused ? R.drawable.ic_track_paused : R.drawable.ic_track_recording;
|
||||
@@ -64,32 +69,47 @@ public class ListItemUtils {
|
||||
|
||||
ImageView iconImageView = (ImageView) view.findViewById(R.id.list_item_icon);
|
||||
iconImageView.setImageResource(iconId);
|
||||
iconImageView.setContentDescription(context.getString(iconContentDescriptionId));
|
||||
iconImageView.setContentDescription(activity.getString(iconContentDescriptionId));
|
||||
|
||||
// Set name
|
||||
TextView nameTextView = (TextView) view.findViewById(R.id.list_item_name);
|
||||
nameTextView.setText(name);
|
||||
|
||||
// Set sharedOwner/totalTime/totalDistance
|
||||
TextView timeDistanceTextView = (TextView) view.findViewById(R.id.list_item_time_distance);
|
||||
if (isRecording) {
|
||||
timeDistanceTextView.setTextColor(context.getResources()
|
||||
timeDistanceTextView.setTextColor(activity.getResources()
|
||||
.getColor(isPaused ? android.R.color.white : R.color.recording_text));
|
||||
} else {
|
||||
// Need to match the style set in list_item.xml
|
||||
timeDistanceTextView.setTextAppearance(context, R.style.TextSmall);
|
||||
timeDistanceTextView.setTextAppearance(activity, R.style.TextSmall);
|
||||
}
|
||||
setTextView(timeDistanceTextView,
|
||||
getTimeDistance(context, isRecording, isPaused, sharedOwner, totalTime, totalDistance),
|
||||
View.INVISIBLE);
|
||||
getTimeDistance(activity, isRecording, isPaused, sharedOwner, totalTime, totalDistance));
|
||||
|
||||
String[] startTimeDisplay = getStartTime(isRecording, context, startTime);
|
||||
// Set photoUrl
|
||||
ImageView photo = (ImageView) view.findViewById(R.id.list_item_photo);
|
||||
if (photoUrl == null || photoUrl.equals("")) {
|
||||
photo.setVisibility(View.GONE);
|
||||
} else {
|
||||
photo.setVisibility(View.VISIBLE);
|
||||
Display defaultDisplay = activity.getWindowManager().getDefaultDisplay();
|
||||
// Set the initial width to 35% of the display width
|
||||
int width = (int) (defaultDisplay.getWidth() * .35);
|
||||
PhotoUtils.setImageVew(photo, Uri.parse(photoUrl), width, 0, false);
|
||||
}
|
||||
|
||||
// Set date/time
|
||||
String[] startTimeDisplay = getStartTime(isRecording, activity, startTime);
|
||||
TextView dateTextView = (TextView) view.findViewById(R.id.list_item_date);
|
||||
setTextView(dateTextView, startTimeDisplay[0], View.GONE);
|
||||
setTextView(dateTextView, startTimeDisplay[0]);
|
||||
|
||||
TextView timeTextView = (TextView) view.findViewById(R.id.list_item_time);
|
||||
setTextView(timeTextView, startTimeDisplay[1], View.GONE);
|
||||
setTextView(timeTextView, startTimeDisplay[1]);
|
||||
|
||||
// Set category/description
|
||||
TextView descriptionTextView = (TextView) view.findViewById(R.id.list_item_description);
|
||||
setTextView(descriptionTextView, getDescription(isRecording, category, description), View.GONE);
|
||||
setTextView(descriptionTextView, getDescription(isRecording, category, description));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -194,11 +214,10 @@ public class ListItemUtils {
|
||||
*
|
||||
* @param textView the text view
|
||||
* @param value the value for the text view
|
||||
* @param visibility visibility when value is not available
|
||||
*/
|
||||
private static void setTextView(TextView textView, String value, int visibility) {
|
||||
private static void setTextView(TextView textView, String value) {
|
||||
if (value == null || value.length() == 0) {
|
||||
textView.setVisibility(visibility);
|
||||
textView.setVisibility(View.GONE);
|
||||
} else {
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
textView.setText(value);
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
*
|
||||
* 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.google.android.apps.mytracks.util;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.ExifInterface;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Utilities for photos.
|
||||
*
|
||||
* @author Jimmy Shih
|
||||
*/
|
||||
public class PhotoUtils {
|
||||
|
||||
private static final String TAG = PhotoUtils.class.getSimpleName();
|
||||
|
||||
private PhotoUtils() {}
|
||||
|
||||
/**
|
||||
* Sets an image view.
|
||||
*
|
||||
* @param imageView the image view
|
||||
* @param uri the image uri
|
||||
* @param displayWidth the display width
|
||||
* @param displayHeight the display height
|
||||
* @param fitWithIn true to fit within the display area. False to crop and fill
|
||||
* the display area.
|
||||
*/
|
||||
public static Bitmap setImageVew(
|
||||
ImageView imageView, Uri uri, int displayWidth, int displayHeight, boolean fitWithIn) {
|
||||
|
||||
// Get the image dimensions
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
|
||||
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));
|
||||
imageView.getLayoutParams().height = targetHeight;
|
||||
}
|
||||
|
||||
// Set imageWidth and imageHeight based on image rotation
|
||||
int rotation = getRotation(uri);
|
||||
int imageWidth;
|
||||
int imageHeight;
|
||||
|
||||
if (rotation == 0 || rotation == 180) {
|
||||
imageWidth = options.outWidth;
|
||||
imageHeight = options.outHeight;
|
||||
} else {
|
||||
imageWidth = options.outHeight;
|
||||
imageHeight = options.outWidth;
|
||||
}
|
||||
|
||||
// Get a scaled down version of the image
|
||||
options.inJustDecodeBounds = false;
|
||||
options.inSampleSize = getInSampleSize(
|
||||
imageWidth, imageHeight, targetWidth, targetHeight, fitWithIn);
|
||||
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) {
|
||||
bitmap = scaledBitmap;
|
||||
} else {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(rotation);
|
||||
bitmap = Bitmap.createBitmap(
|
||||
scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
|
||||
scaledBitmap.recycle();
|
||||
}
|
||||
|
||||
imageView.setImageBitmap(bitmap);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image rotation
|
||||
*
|
||||
* @param uri the image uri
|
||||
*/
|
||||
private static int getRotation(Uri uri) {
|
||||
try {
|
||||
ExifInterface exifInterface = new ExifInterface(uri.getPath());
|
||||
switch (exifInterface.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
return 90;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
return 180;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
return 270;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Unable to get photo orientation", e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the in sample size.
|
||||
*
|
||||
* @param imageWidth the image width
|
||||
* @param imageHeight the image height
|
||||
* @param targetWidth the target width
|
||||
* @param targetHeight the target height
|
||||
* @param fitWithin true to fit within the target area. False to crop and fill
|
||||
* all target area.
|
||||
*/
|
||||
private static int getInSampleSize(
|
||||
int imageWidth, int imageHeight, int targetWidth, int targetHeight, boolean fitWithin) {
|
||||
float widthRatio = 1;
|
||||
if (imageWidth > targetWidth) {
|
||||
widthRatio = (float) imageWidth / (float) targetWidth;
|
||||
}
|
||||
|
||||
float heightRatio = 1;
|
||||
if (imageHeight > targetHeight) {
|
||||
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. To crop and fill the
|
||||
* target area, return the smaller sample ratio so the image will be greater
|
||||
* than the target dimensions. Use Math.floor to not under sample.
|
||||
*/
|
||||
return (int) Math.floor(
|
||||
fitWithin ? Math.max(widthRatio, heightRatio) : Math.min(widthRatio, heightRatio));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user